我们的一些用户仍然使用IE8。在尝试将数据发布到我们的服务器时,有些人偶尔会报告问题(通过标有“保存”的大按钮)。
IE8显示的脚本错误是:对方法或属性访问的意外调用,总是指向KnockoutJS 2.2.0(现在调试)库中的同一行,第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"
});
};
我们在使用这种方法将对象转换为JSON时删除了一些对POST不必要的属性: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);
现在出现了真正的混乱:
答案 0 :(得分:2)
我也遇到过这个问题。深入挖掘我发现了一些事情:
data-bind
中的代码除了由于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);
}
}
});
但是,它停止变得可重现,所以我想出了一个我测试过并且之前工作的hack,只是重试数据解析。所以这个:
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或Knockout问题得到修复之前就已经成功了。
答案 1 :(得分:1)
我不知道这是否会解决它,但您可以使用mapping plugin来介绍JS和JSON:
var mapping = {
'ignore': ["propertyToIgnore", "alsoIgnoreThis"]
}
var viewModel = ko.mapping.toJS(data, mapping);
我试一试,看看它是否有帮助,因为你的方法没有明显的错误。
答案 2 :(得分:0)
你确定是IE8用户遇到了这个问题吗? IE7 does not support JSON.stringify。您需要包含json2.js library以支持IE7及更低版本。