【问题标题】:Knockout.js | Observable array only triggers when last element changes淘汰赛.js |可观察数组仅在最后一个元素更改时触发
【发布时间】:2017-01-14 09:21:39
【问题描述】:

情景

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


问题

我正在处理的问题是我有一个可观察的数组,它通过视图的淘汰赛 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));

【问题讨论】:

    标签: javascript c# knockout.js


    【解决方案1】:

    你没有在本地声明你的第一个 self,所以它是全局的。

    function ItemModel(item) {
      self = this;
    

    应该是

    function ItemModel(item) {
      var self = this;
    

    【讨论】:

    • 天啊...你真是个天才!我不敢相信我错过了,但我想这是因为看了太多的淘汰赛哈哈。如果我能给你一个 cookie,我会的,但我想接受的答案必须这样做。
    【解决方案2】:

    确定何时需要更新计算的淘汰方法有点棘手,您需要在每个 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也有类似的情况@

    希望对你有帮助!

    【讨论】:

    • 虽然这不是我的问题的原因,但这是一个非常有效的观点。我会给你一个好的观点。
    猜你喜欢
    • 2018-03-30
    • 2012-09-08
    • 2013-05-01
    • 2015-01-25
    • 1970-01-01
    • 2015-10-05
    • 2014-06-08
    • 1970-01-01
    相关资源
    最近更新 更多