我不确定我是否了解Knockout.js内部的工作流程。我有一个使用映射插件动态定义的ViewModel。它的形状是:
{ current: { foo: 'foo', bar: 'bar', id: 0 }
, ids: [1,2,3,4,5]
}
其中每个ids
都对应一个属于current
的值。现在,复杂性出现了,因为在填充我的viewModel的初始ajax请求中,服务器以current: null
响应。我编写代码从id
列表中取出第一个ids
并运行另一个ajax查询来填充current
。看起来像这样:
var ViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
self.head = function () {
if (self.promptIds().length != 0) {
var nextId = _.head(self.promptIds());
self.promptIds(_.tail(self.promptIds()));
$.getJSON("my-url" + "/" + nextId, function (data) {
self.current(ko.mapping.fromJS(data));
});
}
}
}
$('document').ready ( function () {
$.getJSON("view-model-route", function (data) {
viewModel = new ViewModel(data);
viewModel.head();
ko.applyBindings(viewModel);
});
});
请注意,在第二个块中,我创建了一个新的ViewModel
对象,并在其上调用head()
。填充viewModel.current()
对象后,我会在完整的ko.applyBindings
上致电viewModel
。我可以确认,当尘埃落定后,viewModel.current
不是null
。但我仍然得到错误:
Uncaught TypeError: Unable to parse bindings.
Bindings value: text: current().foo
Message: Cannot read property 'foo' of null
我是否正在尝试做Knockout没有设计的事情?我需要另一层抽象吗?你会如何处理这种情况?
答案 0 :(得分:2)
当您致电ko.applyBindings
时,首先评估绑定。
因此,如果您的current
属性在此时间内包含null
,那么您获得Cannot read property 'foo' of null
例外是正常的。
这个问题有多种解决方案:
使用空对象初始化current
,以便正确解析current().foo
(但其值为undefined
):
viewModel = new ViewModel(data);
viewModel.head();
viewModel.current({});
ko.applyBindings(viewModel);
您可以在绑定中添加额外条件,以检查current
是否有某些值:
<input type="text" data-bind="value: current() && current().foo" />
如果你正在处理嵌套的proeprties,那么最好也是最推荐的选择是使用with
binding:
<!-- ko with: current -->
<input type="text" data-bind="value: foo" />
<!-- /ko -->
演示JSFiddle。