2013-03-04 2 views
6

Ряд наших пользователей по-прежнему находятся на IE8. Некоторые из них иногда сообщают о проблемах при попытке отправить данные на наши серверы (через большую кнопку с надписью «SAVE»).НокаутJS с IE8, случайные проблемы с Stringify?

Существует ошибка сценария, что IE8 показывает, что: Неожиданный вызов метода или свойства доступа, всегда указывая на той же строке в KnockoutJS 2.2.0 (Debug, на данный момент) библиотеки, строка 450, которая выглядит следующим образом:

return JSON.stringify(ko.utils.unwrapObservable(data), replacer, space); 

метод в моем коде, который находится в корневом каталоге трассировки стека, где это происходит:

self.saveSingle = function (onSuccess, onFailure) { 
     ko.utils.arrayForEach(self.days(), function (day) { 
      day.close(); 
     }); 
     var jsonData = ko.toJSON(self); 
     $.ajax({ 
      type: "POST", 
      contentType: "application/json; charset=utf-8", 
      url: applicationLocation + "/api/assignmentapi/save", 
      data: jsonData, 
      success: function (data) { 
       self.status(data.Status); 
       self._isDirty(false); 
       ko.utils.arrayForEach(self.days(), function (day) { 
        day.clean(); 
       }); 
       if (onSuccess) 
        onSuccess(); 
      }, 
      error: function (data) { 
       onFailure(); 
      }, 
      dataType: "json" 
     }); 
    }; 

Мы раздеться ряд свойств, которые не являются необходимыми к нашему POST, когда мы преобразуем объект для JSON, используя этот подход: http://www.knockmeout.net/2011/04/controlling-how-object-is-converted-to.html

OurType.prototype.toJSON = function() { 
    var copy = ko.toJS(this); 

    delete copy.someUnneededProperty1; 
    delete copy.someUnneededProperty2; 
    delete copy.someUnneededProperty3; 
    delete copy.someUnneededProperty4; 

    return copy; 
} 

Когда он терпит неудачу, он не последовательно на линии

var jsonData = ko.toJSON(self); 

Сейчас здесь идет настоящая неразбериха:

  1. Это не последовательно происходит
  2. Этого не происходит со всеми пользователями IE8
  3. Мы не можем последовательно воспроизвести его
  4. Структура нашей модели, мы сериализации не появляется материя
  5. jscript.dll текущая версия для IE8

ответ

1

Я понятия не имею, если это будет исправить это, но вы можете использовать mapping plugin для перехода между JS и JSON:

var mapping = { 
    'ignore': ["propertyToIgnore", "alsoIgnoreThis"] 
} 
var viewModel = ko.mapping.toJS(data, mapping); 

Взятые из моего answer to this question

Я бы попробовал и посмотрел, помогает ли это, поскольку в вашем подходе нет ничего явно неправильного.

0

Вы уверены, что пользователи IE8 сталкиваются с проблемой? IE7 does not support JSON.stringify. Вам нужно будет включить json2.js library для поддержки IE7 и ниже.

+0

Мы включаем json2 для пользователей IE7. Пользователь IE7 не сообщил о проблеме; только пользователи IE8. – reallyJim

+0

Интересно. Может ли быть, что пользователи IE8 фактически работают в режиме эмуляции IE7 (совместимость с IE-страницей)? –

+0

Наш персонал QA * иногда * способен воспроизвести его, и он находится в режиме IE8, когда они это делают. – reallyJim

2

У меня также возникла эта проблема. Копаем глубже я нашел несколько вещей:

  • Он только не время от времени, я нашел это, запустив код в консоли enter image description here
  • Код в data-bind был trowing исключение, кроме послания проглатывания из-за IE8, поглощающего сообщение при использовании блока try {} finally {} (без catch).
  • Удаление попытки наконец показало, что сообщение синтаксического разбора не удается.

Когда я начал приближаться к выяснению проблемы (копая глубоко в код нокаута), он, казалось, исчезал перед моими глазами. Это часть кода была неисправного на, отлов исключения в конце кода:

ko.utils.extend(ko.bindingProvider.prototype, { 
    'nodeHasBindings': function(node) { 
     switch (node.nodeType) { 
      case 1: return node.getAttribute(defaultBindingAttributeName) != null; // Element 
      case 8: return ko.virtualElements.virtualNodeBindingValue(node) != null; // Comment node 
      default: return false; 
     } 
    }, 

    'getBindings': function(node, bindingContext) { 
     var bindingsString = this['getBindingsString'](node, bindingContext); 
     return bindingsString ? this['parseBindingsString'](bindingsString, bindingContext, node) : null; 
    }, 

    // The following function is only used internally by this default provider. 
    // It's not part of the interface definition for a general binding provider. 
    'getBindingsString': function(node, bindingContext) { 
     switch (node.nodeType) { 
      case 1: return node.getAttribute(defaultBindingAttributeName); // Element 
      case 8: return ko.virtualElements.virtualNodeBindingValue(node); // Comment node 
      default: return null; 
     } 
    }, 

    // The following function is only used internally by this default provider. 
    // It's not part of the interface definition for a general binding provider. 
    'parseBindingsString': function(bindingsString, bindingContext, node) { 
     try { 
      var bindingFunction = createBindingsStringEvaluatorViaCache(bindingsString, this.bindingCache); 
      return bindingFunction(bindingContext, node); 
     } catch (ex) { 
      throw new Error("Unable to parse bindings.\nMessage: " + ex + ";\nBindings value: " + bindingsString); 
     } 
    } 
}); 

Но да, он перестал становится воспроизводимым, поэтому я придумал хака, что я проверил и работает раньше, просто повторить синтаксический анализ данных. Так что это:

data-bind="value: ko.computed(function(){return ko.toJSON(appViewModel.model()[0])})" 

Стала это:

data-bind="value: ko.computed(function(){while (true) { try { var json = ko.toJSON(appViewModel.model()[0]); return json; }catch(e){}}})" 

Да, это очень противный, но это, кажется, сделать трюк, пока наши пользователи больше не нуждаются в IE8 или проблема Нокаут фиксируется.

+0

Хорошо, это yucky. :) Мы прошли это сейчас, создав вместо этого собственные методы toJSON непосредственно в наших объектах. Нижняя сторона заключается в том, что неправильно повторять что-то, что должно было работать, но поскольку мы теперь создаем свои собственные, мне больше не нужно предпринимать шаги по удалению свойств, которые мне не нужны. Я думаю, меч с двойным острием. – reallyJim