动态创建绑定到可观察数组内的可观察对象的复选框不起作用

动态创建绑定到可观察数组内的可观察对象的复选框不起作用

问题描述:

为了更好地理解它是如何工作的,最终导致了一些非常规编码,我一直在使用KnockoutJS。动态创建绑定到可观察数组内的可观察对象的复选框不起作用

这是脚本:

var ViewModel = function() { 
    var self = this; 

    self.counter = ko.observable(0); 
    self.someFruits = ko.observableArray(); 

    self.createbox = function(){ 
     var value = { 
      name: self.counter(), 
      isChecked: ko.observable(true) 
     }; 

     self.someFruits.push(value); 

     $("#div1").append('<div><input type="checkbox" data-bind="checked: someFruits()[' + self.counter() + '].isChecked" /> Cherry</div>'); 

     $("#div2").append('<div><input type="checkbox" data-bind="checked: someFruits()[' + self.counter() + '].isChecked" /> Cherry</div>'); 

     self.counter(self.counter() + 1); 
    } 
}; 

ko.applyBindings(new ViewModel()); 

这里是HTML:

<div> 
    <div> 
     <button data-bind="click: createbox" type="button" class="btn btn-warning">Create Box</button> 
    </div> 

    <div id="div1"> 
    </div> 
    <br> 
    <br> 
    <div id="div2"> 
    </div> 
</div> 

我试图模仿是动态的创建检查盒,这将是数据 - 功能绑定到可观察数组内的可观察对象。所以我做了一个按钮,将push一个新对象包含ko.observableobservableArray。然后使用Jquery添加HTML标记来创建新的复选框。我每次追加两个相同的复选框到不同的div只是为了查看它们是否根据绑定对象进行更新。

它是残酷的,理想情况下,我不应该使用JQuery用于这些目的,也许foreach会很好。但我仍然想明白,为什么这不起作用,当我认为它应该。

编辑:例如,如果我点击3次按钮,将为每个div创建3个复选框,使其在enitre页面*有6个复选框。如果我检查第一个id=div1中的第一个复选框,那么id=div2中的第一个复选框也应同样更新。我一直在使用JSFiddle来测试它,并且复选框不会在单击对应框时自动更新。

在淘汰赛中,你很少需要使用jquery在UI中添加/删除东西。您的viewModel应控制所有添加,删除或任何类型的DOM操作。在你的情况下,你正在推动someFruits observableArray。使用foreach绑定来显示它们。

所以,在下面的代码片段中,我添加了一个输入来添加新的水果。此外,还有一个computed属性,用于在更改复选框时显示“已检查”的水果。

var ViewModel = function() { 
 
    var self = this; 
 
    self.fruitName = ko.observable(); 
 
    self.someFruits = ko.observableArray([]); 
 

 
    self.createbox = function() { 
 
    self.someFruits.push({ 
 
     name: self.fruitName(), 
 
     isChecked: ko.observable(true) 
 
    }); 
 

 
    // clear the input after a fruit is added 
 
    self.fruitName(''); 
 
    } 
 

 
    // every time "someFruits" or "isChecked" changes this gets computed again 
 
    self.checkedFruits = ko.computed(function() { 
 
    return self.someFruits() 
 
     .filter(a => a.isChecked()) 
 
     .map(b => b.name); 
 
    }) 
 
}; 
 

 
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> 
 
<div> 
 
    <div> 
 
    <input data-bind="value: fruitName" /> 
 
    <button data-bind="click: createbox" type="button" class="btn btn-warning">Create Box</button> 
 
    </div> 
 

 
    <div id="div1" data-bind="foreach:someFruits"> 
 
    <div> 
 
     <input type="checkbox" data-bind="checked: isChecked" /> 
 
     <span data-bind="text: name"></span> 
 
    </div> 
 
    </div> 
 
    <br> Selected fruits: 
 

 
    <span data-bind="text: checkedFruits"></span> 
 
</div>
Run Code snippet

点击测试它。 Here's a fiddle如果你想玩它。如果你正在学习淘汰赛,我认为最好不要在一段时间内加入jquery :)

+0

感谢你的工作:)尽管我仍然不明白为什么原文不起作用,它教会了我更简洁的方法当使用KnockoutJS。所以我会接受它。 – CodeIntern

+0

@CodeIntern在'applyBindings()'被调用**后,任何动态添加的带有敲除绑定**的HTML都不起作用。 – adiga

+0

哦,我明白了。这清除了很多疑问。非常感激。 – CodeIntern