代码之家  ›  专栏  ›  技术社区  ›  Laurence Frost

敲除映射-使可观测数组的某些属性成为可观测的

  •  1
  • Laurence Frost  · 技术社区  · 6 年前

    我如何调整下面的代码,以便只有“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>
    

    问题是,我似乎无法调整映射插件,使数据进入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属性是可观察的?

    这是一把小提琴,它显示了这个问题: https://jsfiddle.net/gxreh8sy/27/

    1 回复  |  直到 6 年前
        1
  •  3
  •   Jason Spake    6 年前

    您要寻找的选项是“观察”映射选项。从 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"});
        }
    };