Binding 敲除绑定不适用于数组

Binding 敲除绑定不适用于数组,binding,knockout.js,Binding,Knockout.js,我试图做以下工作:(参见JSFIDLE中的示例:) javascript: var originalData = { id: 1, name: "Main", children: [ { id: 2, name: "bob" }, { id: 3, name: "ted" } ], selectedChild: { id: 2, name: "bob" } }; var viewModel = ko.mapping.fromJS(originalData); viewModel.sele

我试图做以下工作:(参见JSFIDLE中的示例:)

javascript:

var originalData = {
id: 1,
name: "Main",
 children: [ { id: 2, name: "bob" }, { id: 3, name: "ted" } ],
selectedChild:  { id: 2, name: "bob" }
};

var viewModel = ko.mapping.fromJS(originalData);

viewModel.selectChild = function(){
   var obj =  { id: 9, name: "new" };

   viewModel.selectedChild(obj);
}  

ko.applyBindings(viewModel);
HTML:


这太烦人了。为什么我需要隐式地将属性设置为可观察?另外,如果我不给它一个默认值,它将无法工作。为什么?

您应该使
selectedChild
成为一个计算的可观察对象,它将返回所选的子对象。添加一个可观察对象,该对象将跟踪所选的子对象。只需跟踪
id
(或唯一标识子项的任何属性)

然后,为了使显示所选子对象更容易,如果选择了有效的子对象,请使用带绑定的进行有条件渲染

<div data-bind="with: selectedChild">
    <span data-bind="text: name"></span>
</div>


好的,我想这是因为selectedChild是不可见的。有人能给我看一下代码,让它成为一个可观察的属性吗?谢谢你的帮助。不过,我需要将selectedChild对象作为数据的一部分。我不能只有一个id。我已经创建了一个新的JSFIDLE来更好地显示我的问题。请参见,它有两个问题:1)数组的长度不会显示在视图中(尽管它肯定会发生变化,正如您在“警报”框中看到的那样)。2) 所选学生也不会显示在视图中。你能帮我让这个样本工作,因为它更符合我想要实现的目标吗?谢谢你(jsfiddle:)在这里,你只需要像我已经展示的那样,使用带有绑定的
。您看到的问题是
selectedChild
初始为空。应用绑定时,
selectedChild().name
部分会断开所有绑定。通过在此处使用
,它不会引起问题。另外,在访问绑定中的属性时要小心,否则您会看到这种情况。请注意控制台正在记录的内容,您将看到我所指的错误。是的,确实需要with。现在选定的学生出现了。但是数组的长度仍然没有显示出来。请参阅更新的JSFIDLE:知道缺少什么吗?同样的问题。
students
数组最初是空的,因此您应该再次使用带有
绑定的
。或者您可以在
originalData
中将数组初始化为空而不是空。
<span data-bind="text: selectedChild().name"></span>
viewModel.selectedChild = ko.observable(viewModel.children()[0]);
var originalData = {
    id: 1,
    name: "Main",
    children: [{
        id: 2,
        name: "bob"
    }, {
        id: 3,
        name: "ted"
    }],
    selectedId: 2
};

var viewModel = ko.mapping.fromJS(originalData);
viewModel.selectedChild = ko.computed(function() {
    var selectedId = this.selectedId(),
        children = this.children();

    // get the first child that has the same id as the selectedId
    return ko.utils.arrayFirst(children, function(child) {
        return child.id() === selectedId;
    });
}, viewModel);
<div data-bind="with: selectedChild">
    <span data-bind="text: name"></span>
</div>