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

标签 javascript jquery html checkbox knockout.js

我一直在研究 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>

我试图模拟的是动态创建复选框的功能,这些复选框将数据绑定(bind)到可观察数组内的可观察对象。因此,我制作了一个按钮,将push一个新对象,该对象将包含ko.observableobservableArray中。然后使用 Jquery 附加 HTML 标记来创建新的复选框。我每次将两个相同的复选框附加到不同的 div 只是为了查看它们是否根据绑定(bind)对象进行更新。

这很残酷,理想情况下,我不应该将 JQuery 用于这些目的,也许 foreach 在这里会很好。但我仍然想了解为什么当我认为它应该起作用时却不起作用。

编辑:例如,如果我单击按钮 3 次,将为每个 div 创建 3 个复选框,从而使整个页面中总共有 6 个复选框。如果我选中第一个 id=div1 中的第一个复选框,那么 id=div2 中的第一个复选框也应该同样更新。我一直在使用 JSFiddle 来测试这一点,当单击对应的复选框时,复选框不会自动更新。

最佳答案

在 knockout 中,您很少需要使用 jquery 从 UI 中添加/删除内容。您的 viewModel 应该控制所有添加、删除或任何类型的 DOM 操作。就您而言,您正在推送到 someFruits observableArray。使用foreach绑定(bind)以显示它们。

因此,在下面的代码片段中,我添加了一个输入来添加新水果。另外,一个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>

单击运行代码片段进行测试。 Here's a fiddle如果你想玩玩它。如果你正在学习 knockout ,我认为最好暂时不要包含 jquery :)

关于javascript - 动态创建绑定(bind)到可观察数组内的可观察对象的复选框不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47490046/

相关文章:

Javascript - 全局范围或局部范围,无法弄清楚

jQuery $ ('.div' ).each 只运行一次迭代

html - CSS网格: Don't expand grid items

javascript - 如何将 HTML block 动态添加到页面中?

Javascript 附加到 onClick 事件

javascript - 为什么 Knockout 不会因模型更改而自动更新?

javascript - 在 Canvas 中心写(0,0)-HTML5

javascript - 从场景中移除所有物体的正确方法

jquery - $.ajax 上下文选项

jquery - 我如何获取 jquery-ui 自动完成小部件的上下文?