如何在可观察数组中创建一个项目会更改该数组中的另一个项目

时间:2016-02-22 06:39:48

标签: knockout.js

我有一个带有可观察属性的对象数组,该属性被绑定到一组单选按钮。可观察的属性只能具有以下值['主要','次要','偶尔','无']

这是HTML。

<!--ko foreach: allDriversForPolicy-->
<div class="col-md-2">
    <a href="#" class="thumbnail">
        <div class="">
            <label><input type="radio" value="Primary" data-bind="checked: vehicleDriverType, attr: {name: id}"/>Primary</label>
            <label><input type="radio" value="Secondary" data-bind="checked: vehicleDriverType, attr: {name: id}" />Secondary</label>
            <label><input type="radio" value="Ocasional" data-bind="checked: vehicleDriverType, attr: {name: id}" />Ocasional</label>
            <label><input type="radio" value="" data-bind="checked: vehicleDriverType, attr: {name: id}" />None</label>
        </div>
    </a>
</div>
<!--/ko-->

这是让它运行的JavaScript。

var SimpleListModel = function() {
    this.allDriversForPolicy = ko.observableArray([
    {'id': 'abe', 'vehicleDriverType': 'Primary'},
    {'id': 'bob', 'vehicleDriverType': 'Secondary'},
    {'id': 'charlie', 'vehicleDriverType': ''}
    ]);
};

ko.applyBindings(new SimpleListModel());

jsfiddle是here。 我遇到的皱纹是一个额外的要求,在所有对象中只有一个主要因素,所以我想要选择Primary时的行为,然后遍历数组并使用observable属性集切换任何对象“初级”到“中学”。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

注意:你有一个相当奇怪的标记位,a标记包含所有其他代码。我在下面的示例中删除了该位。

您的要求非常难以在MVVM / Knockout样式中实现,因为您没有为所选单选按钮值提供后备可观察性。更改后,您可以选择多种方式来实现您的要求,包括:

  • 为后备可观察对象创建writeable computeds,其中write位更新兄弟可观察量;
  • 创建对所有单个支持可观察对象的订阅。

这是后一种选择的一个例子:

&#13;
&#13;
var SimpleListModel = function() {
  var self = this;
  
  this.allDriversForPolicy = ko.observableArray([{
    'id': 'abe',
    'vehicleDriverType': ko.observable('Primary')
  }, {
    'id': 'bob',
    'vehicleDriverType': ko.observable('Secondary')
  }, {
    'id': 'charlie',
    'vehicleDriverType': ko.observable('')
  }]);
  
  self.allDriversForPolicy().forEach(function(i) {
    i.vehicleDriverType.subscribe(function(newVal) {
      if (newVal !== 'Primary') return;
      self.allDriversForPolicy().forEach(function(p) {
        if (p !== i && p.vehicleDriverType() === 'Primary') {
          p.vehicleDriverType('');
        }
      });
    });
  });
};

ko.applyBindings(new SimpleListModel());
&#13;
pre { background: white; padding: 10px; color: #333; font: 11px consolas; border: 1px solid #ddd; }
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<!--ko foreach: allDriversForPolicy-->
<div class="col-md-2">
  <div class="">
    <label>
      <input type="radio" value="Primary" data-bind="checked: vehicleDriverType, attr: {name: id}" />Primary</label>
    <label>
      <input type="radio" value="Secondary" data-bind="checked: vehicleDriverType, attr: {name: id}" />Secondary</label>
    <label>
      <input type="radio" value="Ocasional" data-bind="checked: vehicleDriverType, attr: {name: id}" />Ocasional</label>
    <label>
      <input type="radio" value="" data-bind="checked: vehicleDriverType, attr: {name: id}" />None</label>
  </div>
</div>
<!--/ko-->

<hr>Debug info: <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
&#13;
&#13;
&#13;

PS。我建议为该数组中的项创建一个单独的构造函数,这将产生更清晰的代码(如果你这样做,嵌套的forEach将变得更好)。