Knockout.js | Observable数组仅在最后一个元素更改时触发

时间:2016-09-06 20:14:28

标签: javascript c# knockout.js

情景

我有多个输入字段。字段不允许为空。如果任何字段为空,我想显示某种错误消息。

问题

我正在处理的问题是我有一个可观察的数组,通过一个淘汰的foreach为视图填充一些输入。

所有内容都正确加载,显示和保存,但是,我的验证(计算)仅在可观察数组中的最后一个元素发生更改时调用,而不是在任何其他元素发生更改时调用。

我找到了This SO Question,但OP在这里的问题是他/她没有将其值作为可观察量而不是我的问题,因为我的值被包装为可观察的。

守则

Here's a fiddle

以下是代码:

查看

<div data-bind="with: itemsModel">
  <label data-bind="text: validMessage">Totally valid</label>
  <div data-bind="foreach: items">
    <div>
      <label>Item: </label>
      <input type="text " data-bind="value: name " />
    </div>
  </div>
</div>

JS

function ItemModel(item) {
  self = this;
  self.item = item;

  self.name = ko.observable(item.name);

  self.isValid = ko.computed(function() {
    return self.name() && self.name().length <= 256;
  });
}

function ItemsModel(itemsModel) {
  var self = this;
  self.itemsModel = itemsModel;

  self.items = ko.observableArray([
    new ItemModel(itemsModel.items[0]),
    new ItemModel(itemsModel.items[1]),
    new ItemModel(itemsModel.items[2])
  ]);

  // This is only getting called when the last element in self.items changes
  self.isValid = ko.computed(function() {
    var isValid = true;

    for (i = 0; i < 3; i++) {
      isValid = isValid && self.items()[i].isValid();
    }

    return isValid;
  });

  self.validMessage = ko.computed(function() {
    if (self.isValid()) {
      return "Totally Valid";
    }

    return "Totally NOT Valid";
  });
}

function ViewModel(data) {
  var self = this;
  self.data = data;

  self.itemsModel = ko.observable(new ItemsModel(data.itemsModel));
}

var modelData = {
  itemsModel: {
    items: [{
      name: "Item One"
    }, {
      name: "Item Two"
    }, {
      name: "Item Three"
    }]
  }
};

ko.applyBindings(new ViewModel(modelData));

2 个答案:

答案 0 :(得分:2)

您未在本地声明您的第一个self,因此它是全球性的。

function ItemModel(item) {
  self = this;

应该是

function ItemModel(item) {
  var self = this;

答案 1 :(得分:1)

确定何时计算需要更新的淘汰方法有点棘手,你需要至少执行一次每个observable才能让它们注册。

尝试这样的事情。

  self.isValid = ko.computed(function() {
    var isValid = true;

    for (i = 0; i < 3; i++) {
      //if isValid is false second part will not executed
      //isValid = isValid && self.items()[i].isValid(); 

      isValid = self.items()[i].isValid() && idValid;
    }

    return isValid;
  });

我在https://stackoverflow.com/a/38131131/2233835

有类似的案例

希望它有所帮助!