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

Knockout mapping - making only some properties of an observableArray become observable

我如何调整下面的代码,以便只有 "viewNotes" 属性 变得可见?

我需要从服务器读取数据并将其应用于 ObservableArray。在数据的所有属性中,只有 viewNotes 属性需要是可观察的。其他一切都不需要 2 路数据绑定。

这是来自服务器的数据:

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>

问题是我似乎无法调整映射插件以将数据带入 observableArray,每个数组元素只有 "viewNotes" 属性 可观察。这是我的代码:

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 属性是可观察的?

这里有一个 Fiddle 显示了这个问题: https://jsfiddle.net/gxreh8sy/27/

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

If you want the mapping plugin to only create observables of some properties of your JS object and copy the rest, you can specify an array of propertynames to observe:

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

但是,在您的情况下,属性 不存在于根级别,因为它位于项目数组的每个子级上。因此,您可以先循环并在循环中映射数组的每个项目,也可以使用带有回调函数的 "create" 映射选项来为每个子对象指定一个子映射。

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