淘汰赛检查绑定并选择所有子项集合 [英] Knockout checked binding and select all children collection

查看:66
本文介绍了淘汰赛检查绑定并选择所有子项集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Knockout组件,该模板可打印两个嵌套的项列表(我的界面中的复选框):第一个foreach循环遍历一些父项"项,第二个(嵌套)列表遍历每个父项,以及,如果找到孩子,则打印孩子.要求是,如果用户单击父项(即父项复选框),则所有子项复选框都将被选中.

I have a Knockout component which template prints two nested lists of items (checkboxes in my interface): a first foreach loop iterates through some "parents" items, a second (and nested) list iterates through each of the parents items and, if children are found, prints the children. The requirement is that if the user clicks on a parent item (that is, on a parent checkbox), all the children checkboxes become checked.

在我的代码中,父母和孩子复选框都侦听可观察对象,该对象首先设置为false,然后在选择父对象时设置为true-结果:选择了父母的孩子. 我的问题是,这样,由于每个复选框都监听相同的可观察对象,因此我最终选择了所有复选框,而不仅仅是我选择的父母和孩子,这就是我想要的.

In my code, both parents and children checkboxes listen to an observable that is first set to false and then, when a parent is selected, is set to true - result: that parent's children get selected. My issue is that, this way, since every checkbox listen to the same observable, I end up with ALL the checkboxes selected, not only my selected parents + children, which is what I want.

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

Not sure how I should approach this issue some other way, here is my code:

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>'
});

更新: JSON看起来像这样:

UPDATE: JSON looks like this:

[{
"id": 4,
"members": [
    {
        "last_modified_date": "2016-08-04T14:59:25.958Z",
        "id": 31,
        "label": "Backgrounders & Information Notes"
    },
    {
        "last_modified_date": "2016-08-04T14:59:25.961Z",
        "id": 32,
        "label": "Biographies"
    },
],
"label": "Event-/Stakeholder related documentation",
},
{
"id": 2,
"members": [
    {
        "last_modified_date": "2016-08-04T14:59:25.875Z",
        "id": 1,
        "label": "Books"
    },
    {
        "last_modified_date": "2016-08-04T14:59:25.878Z",
        "id": 2,
        "label": "Briefs, Summaries, Synthesis, Highlights"
    },
],
"label": "Publications"
}]

谢谢.

推荐答案

您应该通过扩展具有computed属性的doctype(取决于各个成员的状态)来稍微准备数据.成员还应包含observable属性以跟踪其已检查状态.

You should slightly prepare your data by extending doctypes with computed property that depends on the state of respective members. Also members should contain observable property to track their checked state.

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

The best place to implement such preparations will be (I guess) the callback where you initialize types property with decoded JSON response:

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

因此,使用 Roy J (由 user3297291 创作)提出的小提琴方法,您将获得类似以下内容的信息:

So using the approach from the fiddle mentioned by Roy J (and authored by user3297291) in comments you will get something like:

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属性的更改!

The code is copied from my fiddle where I'd decomposed your component to the usual view model, and property names are different. Pay your attention to changes in data-bind attributes too!

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

这篇关于淘汰赛检查绑定并选择所有子项集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆