javascript - knockout 循环中的嵌套绑定(bind)

标签 javascript jquery html knockout.js

我继续学习 knockout ,并继续面临我不知道如何克服的奇怪问题。

我有以下 html 页面和 js 脚本:

HTML:

<div data-bind="debug: $data, foreach: objects">
    <span hidden="hidden" data-bind="value: type.id"></span>
    <input type="text" data-bind="value: type.title" />
    <button type="button" data-bind="click: $parent.removeObject">- </button>
  </div>
  <div class="control-group form-inline">
    <select data-bind="options: availableTypes, optionsValue: function(item) {return item;},
                        optionsText: function(item) {return item.title;}, value: itemToAdd.type,
                        optionsCaption: 'Select types...'"></select>
    <button type="button" data-bind="click: addObject">+</button>
  </div>
</div>  

JS:

function model() {
  var self = this;

  var types = [new Type("1"), new Type("2"), new Type("3")];
  var objects = [new Object("1")];

  self.objects = ko.observableArray(objects);

  self.usedTypes = ko.computed(function() {
    return types.filter(function(type) {
      for (var j = 0; j < self.objects().length; j++) {
        if (self.objects()[j].type.id === type.id) {
          return true;
        }
      }
      return false;
    });
  }, self);

  self.availableTypes = ko.computed(function() {
    return types.filter(function(type) {
      for (var j = 0; j < self.usedTypes().length; j++) {
        if (self.usedTypes()[j].id === type.id) {
          return false;
        }
      }
      return true;
    });
  }, self);

  self.itemToAdd = new Object();

  self.addObject = function() {
    self.objects.push(self.itemToAdd);
    self.itemToAdd = new Object();
  };

  self.removeObject = function(object) {
    self.objects.remove(object);
  };
};

function Object(type) {
  var self = this;
  self.type = new Type(type);
}

function Type(id) {
  var self = this;
  self.id = id;
  self.title = id;
}
ko.applyBindings(new model());

我简化了模型来显示错误。问题是 knockout 声称这样做是非法的:
<span hidden="hidden" data-bind="value: type.id"></span>
因为它找不到属性id在上下文中。据我所知,它就在那里,一切都很好。

有人可以指出我的错误吗?

附:这是JsFiddle

添加
感谢@Daryl 的帮助,我能够定位问题。如果我更换

  self.itemToAdd = new Object();

  self.addObject = function() {
    self.objects.push(self.itemToAdd);
    self.itemToAdd = new Object();
  };

与:

  self.itemToAdd = new Object();

  self.addObject = function() {
    self.objects.push(new Object(1));
    self.itemToAdd = new Object();
  };  

但是,下面的代码仍然不起作用:

  self.itemToAdd = new Object("1");

  self.addObject = function() {
    self.objects.push(self.itemToAdd);
    self.itemToAdd = new Object();
  };  

看来itemToAdd对象从其绑定(bind)的 html 元素中填充不正确。但我还是不知道到底出了什么问题。

最佳答案

您已允许取消设置类型下拉列表。当 knockout 显示标题时,它会清除实际值。这意味着,通过渲染 UI,您的 itemToAdd.type 将被清除。

您的第二种方法通过不使用数据绑定(bind)实例来解决此问题。

此外:

  • 如果我是你,我就不会覆盖 Object 构造函数...找一个不同的名称。
  • 如果您想与 UI 进行双向绑定(bind),请确保您的 itemToAdd 具有可观察的属性。

关于javascript - knockout 循环中的嵌套绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39836124/

相关文章:

html - 如何编写一个停止/中断无限循环 Rails 应用程序的 Web 按钮?

javascript - 支持/反对在 html 正文标记中使用内联 javascript 有什么好的论据?

html - 如何使图像保持相同大小

javascript - 自定义 CSS 复选框 jQuery 诱导的 "checked"属性在视觉上不显示 "check"复选框

javascript - 如何在没有任何 ID 的情况下在 javascript DOM 中定位 ul 和 li 中的某个元素

javascript - 如何将函数应用于具有相同类的所有新元素,但仅限于新创建的元素? (JS函数)

jquery事件监听位置改变

javascript - 如何在 iFrame 上显示图像?

javascript - 在网站上使用 HTML/CSS 生成器是否合法?

javascript - 如何在单击按钮时重复向变量添加 +1?