Knockout检查绑定并选择所有子集合

时间:2016-08-06 22:01:41

标签: knockout.js

我有一个Knockout组件,该模板打印两个嵌套的项目列表(我的界面中的复选框):第一个foreach循环遍历一些" parent" items,第二个(和嵌套的)列表遍历每个父项,如果找到子项,则打印子项。要求是,如果用户单击父项(即,在父复选框上),则会选中所有子项复选框。

在我的代码中,父母和子女复选框都会侦听首先设置为false的observable,然后在选择父级时将其设置为true - 结果:父亲的子项被选中。 我的问题是,这样,因为每个复选框都听同一个observable,我最终会选中所有选中的复选框,而不仅仅是我选择的父母+孩子,这就是我想要的。

我不确定如何以其他方式处理此问题,这是我的代码:

someClass

更新 JSON看起来像这样:

ko.components.register("types",{ 
viewModel: function(){
var self = this;

// Data
self.types = ko.observableArray();
self.isPChecked = ko.observable(false);
nut.structuredDocumentTypes()
  .done(function (types) {
    self.types(types);
  });

// Behaviours
self.selectChildren = function(parent) {
  self.isPChecked(true);
  console.log(self.isPChecked(),parent);
}
},
template: 
'<div id="doctypes" class="wfp-form wfpTreeList">\
  <h2 class="hidden">Document Types</h2>\
  <ul class="wfpList" data-bind="foreach: types">\
    <!-- ko if: $index() > 0 -->\
    <li class="root">\
      <input\
        type="checkbox"\
        name="types"\
        class="wfp-checkbox"\
        data-select="multi"\
        data-bind="\
          checked: $component.isPChecked,\
          event: { change: $component.selectChildren },\
          value: $data.id">\
      <input\
        type="checkbox"\
        name="acc"\
        data-bind="\
          attr: { class: \'lvl\' + $data.id, id: \'acc\' + $data.id }">\
      <label\
        data-bind="attr: { for: \'acc\' + $data.id }">\
          <i class="ico-angle-down"></i>\
      </label>\
      <span data-bind="text: $data.label" class="root-title"></span>\
      <ul data-bind="attr: { \'data-lvl\': \'lvl\' + $index(), id: \'lvl\' + $data.id }">\
        <!-- ko foreach: $data.members -->\
          <li>\
            <label data-bind="attr: { for: \'dt-child-\' + $parent.id + \'-\' + $index() }">\
              <input\
                name="types"\
                type="checkbox"\
                data-bind="\
                  checked: $component.isPChecked,\
                  value: $data.id,\
                  attr: { id: \'dt-child-\' + $parent.id + \'-\' + $index() }">\
              <span data-bind="text: $data.label"></span>\
            </label>\
          </li>\
        <!-- /ko -->\
      </ul>\
    </li>\
  <!-- /ko -->\
  </ul>\
</div>'
});

谢谢大家。

1 个答案:

答案 0 :(得分:1)

您应该通过扩展具有computed属性的文档类型来略微准备您的数据,该属性取决于各个成员的状态。成员还应包含observable属性以跟踪其已检查状态。

实现此类准备的最佳位置(我猜)是使用解码的JSON响应初始化types属性的回调:

nut.structuredDocumentTypes()
    .done(function (types) {
        // we'll prepare types here
        self.types(types);
    });

因此,在评论中使用 Roy J (并由 user3297291 撰写)的小提琴方法,你会得到类似的结果:

nut.structuredDocumentTypes()
    .done(function (types) {

        types.forEach(function(type){
            type.members.forEach(function(member){
                member.isSelected = ko.observable(false);
            });
            type.isSelected = ko.computed({
                read: function(){
                    return type.members.every(function(member){
                        return member.isSelected();
                    });
                },
                write: function(selected){
                    type.members.forEach(function(member){
                        member.isSelected(selected);
                    });
                }
            });
        });

        self.types(types); // insert prepared data
    });

从我的小提琴中复制代码,我将组件分解为通常的视图模型,属性名称不同。请注意data-bind属性的变化!

https://jsfiddle.net/ostgals/z8vshLow/

相关问题