基于可观察数组

时间:2016-12-12 04:55:32

标签: knockout.js

我有一个像这样的对象列表

   function Person(id,name,age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    var listOfPeople = [
        new Person(1, 'Fred', 25),
        new Person(2, 'Joe', 60),
        new Person(3, 'Sally', 43)
    ];

    var viewModel = {
        people: ko.observableArray(listOfPeople),
        selectedPeople: ko.observableArray([1])
    };


    ko.applyBindings(viewModel);

我想建立一个复选框列表,每个人一个。它到目前为止工作正常。

现在我的困惑是如何只启用某些数组中的特定复选框,类似于选定的人。

我试过这段代码,但它无法运作

  <ul data-bind="foreach: people">
    <li>
        <input type="checkbox" value="" data-bind="checkedValue: id, checked: $parent.selectedPeople, enable:$parent.selectedPeople" ><span data-bind="text: name"></span>
    </li>
</ul>

<hr/>

<div data-bind="text: ko.toJSON($root)"></div>

2 个答案:

答案 0 :(得分:0)

你必须有另一个属性,让我们说enabled来执行此操作。你可以尝试这样的事情,

function Person(id, name, age) {
  this.id = id;
  this.name = name;
  this.age = age;
}

var listOfPeople = [
  new Person(1, 'ABC', 25),
  new Person(2, 'BCD', 60),
  new Person(3, 'CDE', 43)
];

var viewModel = {
  people: ko.observableArray(listOfPeople),
  selectedPeople: ko.observableArray([1]),
  activePeople: ko.observableArray([1, 3]),
  isEnabled: function(id) {
    return this.activePeople().some(function(activeId) {
      return activeId === id;
    });
  }
};

ko.applyBindings(viewModel);
<ul data-bind="foreach: people">
  <li>
    <input type="checkbox" value="" data-bind="checkedValue: id, checked: $parent.selectedPeople, enable: $parent.isEnabled(id)"><span data-bind="text: name"></span>
  </li>
</ul>

<hr/>

<div data-bind="text: ko.toJSON($root)"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

答案 1 :(得分:0)

您可以检查属性的值是否等于selectedPeople对象中相同属性的值,并根据需要使用此等式enabledisable如下 -

<ul data-bind="foreach: people">
  <li>
    <input type="checkbox" data-bind="checkedValue: id, checked: selectedPeople().ifSelected, enable: selectedPeople().ifSelected === ifSelected"><span data-bind="text: name"></span>
  </li>
</ul>

您可以注意到boolean对象中的其他ifSelected属性Person,此处正在使用此属性进行此等同。但是,这种比较应该是任何种类(字符串,范围,数字相等等),但应该评估为bool。

小提琴here

修改

在查看您从服务器获取数据的评论之后,您可以通过以下方式创建一个自定义Persons类,其中包含ifEnabled属性以处理checkboxenable

function Persons(data) {
    var self = this;
    if (data !== null) {
      self.name = data.name;
      self.id = data.id;
      self.age = data.age;
      // only below properties are observables.
      self.ifSelected = ko.observable(false);
      // below comparison will decide which check box to enable.
      self.ifEnabled = ko.observable(self.age > 50);
    }
}

现在,正如我在这里对其他答案的评论中所提到的,你可以使用knockout的映射插件将这个附加属性插入到Person对象中,如下所示 -

var mappingOptions = {
    create: function(options) {
      return new Persons(options.data);
    }
}; 

正如您所看到的,这就是您可以根据需要创建observable的方法,并将它们保留为您不希望映射到可观察对象的普通值。

最后,下面的代码为您的绑定创建了所需的people数组 -

var persons = ko.mapping.fromJS(listOfPeople, mappingOptions);    
self.people = ko.observableArray(persons());

更新了小提琴here