剔除映射-仅使observableArray的某些属性变为可观察的

时间:2018-06-26 16:49:34

标签: knockout.js knockout-mapping-plugin knockout-3.0

如何调整下面的代码,以便仅“ viewNotes”属性可观察?

我需要从服务器读取数据并将其应用于ObservableArray。在数据的所有属性中,仅viewNotes属性需要是可观察的。其他所有内容都不需要双向数据绑定。

以下是来自服务器的数据:

var data = [
  {
    "itemName": "Item 1",
    "notes": "This is item 1",
    "viewNotes": false
  },
  {
    "itemName": "Item 2",
    "notes": "This is item 2",
    "viewNotes": false
  }
]

然后我将其数据绑定到页面,如下所示。想法是显示数据,但是除非用户单击查看,否则隐藏“ notes”属性。此可见性切换开关链接到viewNotes属性-因此它必须是可观察的,而其他操作则无济于事。

<div data-bind="foreach: items">
  <div data-bind="text: itemName"></div>
  <button data-bind="click: $parent.viewTheNotes">View Notes</button>
  <div data-bind="if: viewNotes">
    <div data-bind="text: notes"></div>
  </div>
  <hr>
</div>

问题是我似乎无法调整映射插件以仅将每个数组元素的“ viewNotes”属性视为可观察的数据,从而将数据带入observableArray。这是我的代码:

var mapping = {
  "include": ["viewNotes"]
};

ko.mapping.fromJS(data, mapping, self.items);
alert("is viewNotes observable: " + ko.isObservable(self.items()[0].viewNotes));
alert("is itemName observable: " + ko.isObservable(self.items()[0].itemName));

如您所见,警报框告诉我们,每个数组元素的所有子属性似乎都已映射到可观察对象。

我该如何调整它以便只能查看viewNotes属性?

以下是显示该问题的小提琴: official docs

1 个答案:

答案 0 :(得分:3)

您要查找的选项是“观察”映射选项。来自http://knockoutjs.com/documentation/plugins-mapping.html

  

如果您希望映射插件仅创建某些对象的可观察对象   JS对象的属性并复制其余部分,您可以指定一个   要观察的属性名称数组:

var mapping = {
    'observe': ["propertyToObserve"] } var viewModel = ko.mapping.fromJS(data, mapping);
}

但是,在您的情况下,该属性在根级别不存在,因为它位于一系列项的每个子项中。因此,您可以先循环并在循环中映射数组的每个项目,也可以将“创建”映射选项与回调函数一起使用,以为每个子对象指定一个子映射。

var mapping = {
    create: function(options){
        return ko.mapping.fromJS(options.data, {observe: "viewNotes"});
    }
};