Knockout js绑定可空对象的属性

时间:2018-04-11 14:18:48

标签: javascript knockout.js knockout-mapping-plugin

我有一个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调用返回之前的错误,targetFieldconditionalOperatornull

如果绑定对象不存在,可以使用额外的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更改则需要更新。

有没有更好的方法让它发挥作用?

1 个答案:

答案 0 :(得分:2)

一个简单的解决方案可能是创建一个knockout observable变量并将其设置为false,直到您获得API返回的数据为止。然后将div包含在ko if:绑定 -

中的observable包裹起来
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-->

可能有更优雅的方式处理这个,但这取决于很多事情。正如我所说,这是我能想到的最简单的解决方案:)