我有一个knockout.js页面,它从API加载数据并使用knockout映射插件将数据转换为ViewModel上的参数。
数据包含嵌套对象,例如
[{
id: 1,
targetField: {
id: 132,
name: 'Field ABC',
...
},
conditionalOperator: {
id: 8,
display: 'Less Than'
},
conditionalValue:13
},
...
]
加载到页面视图模型
var PageViewModel = function() {
...
this.allConditionLogic = ko.observableArray();
}
var pageViewModel = new PageViewModel();
$.get('api/...')
.done(function(data) {
pageViewModel.allConditionLogic(ko.mapping.fromJS(data));
});
html包含对象的绑定
<div data-bind="foreach: allConditionLogic">
<p>Field id <span data-bind="text: targetField().id"></span> <span data-bind="text: conditionalOperator().display"></span> <span data-bind="text: conditionalValue"></span></p>
</div>
然而,在ajax调用返回之前的错误,targetField
和conditionalOperator
为null
。
如果绑定对象不存在,可以使用额外的span
元素和不创建内部html的with
绑定 - 例如。
<p>Field id <span data-bind="with: targetField"><span data-bind="text: id"></span> <span data-bind="with: conditionalOperator"><span data-bind="text: display"></span></span> <span data-bind="text: conditionalValue"></span></p>
然而,这种接缝有点矫枉过正。我可以使用正确的字段在allConditionLogic
中定义一个空白对象,但这需要更多的输入,如果API更改则需要更新。
有没有更好的方法让它发挥作用?
答案 0 :(得分:2)
一个简单的解决方案可能是创建一个knockout observable变量并将其设置为false
,直到您获得API返回的数据为止。然后将div
包含在ko if:
绑定 -
var PageViewModel = function() {
this.allConditionLogic = ko.observableArray();
//Set it to false initially
this.hasAPIreturnedData = ko.observableArray(false);
}
var pageViewModel = new PageViewModel();
$.get('api/...')
.done(function(data) {
pageViewModel.allConditionLogic(ko.mapping.fromJS(data));
//make it true after data is returned and is transformed
pageViewModel.hasAPIreturnedData(true);
});
<!--ko if: hasAPIreturnedData -->
<div data-bind="foreach: allConditionLogic">
<p>Field id <span data-bind="text: targetField().id"></span> <span data-bind="text: conditionalOperator().display"></span> <span data-bind="text: conditionalValue"></span></p>
</div>
<!--/ko-->
可能有更优雅的方式处理这个,但这取决于很多事情。正如我所说,这是我能想到的最简单的解决方案:)