复杂对象传递到ko.mapping.fromJS

时间:2013-04-03 20:07:25

标签: javascript jquery knockout.js knockout-mapping-plugin knockout-2.0

我有一个复杂的对象,我想传递给ko.mapping.fromJS,我的问题是我只想要一个字段是可观察的,但其他属性根据方法我或者是空的或不存在的试过了。

我创建了一个jsFiddle here来说明我的问题。我希望简单地复制内部对象,因为我不需要它是可观察的;考虑到我将拥有的这些数量,我不想要额外的开销。

这样做的目的是让qty可编辑,但inner.name在文本框中保持不变。这意味着一个是可观察的,而另一个则不是。

如果任何人有另一种方式做这个不涉及映射,我很乐意听到它。我的视图模型有很多功能等,数据来自AJAX调用。

function viewModel() {
    var self = this;
    self.slots = ko.observableArray([]);

    self.load = function() {
        ko.mapping.fromJS(
            [
                { 'qty': 1, 'inner': { 'name': 'thing'} },
                { 'qty': 2, 'inner': { 'name': 'stuff'} }
            ],
            { 'include': ['qty'], 'ignore': ['inner.name'] },
            self.slots);
    }
};

ko.applyBindings(new viewModel());

<button data-bind="click: load">Go</button>
<ul data-bind="foreach: slots">
    <li>
        <span data-bind="text: qty"></span>&nbsp;<span data-bind="text: inner.name"></span><input data-bind="value: qty" /><input data-bind="value: inner.name" />
    </li>
</ul>

1 个答案:

答案 0 :(得分:4)

您需要使用copy代替ignore,因为您希望其中的属性无法被观察到。

因为您直接映射数组,映射配置变得有点复杂。

您无法在“根”级别定义copy,因为您在根目录中有数组。因此,您必须为项目提供create函数,现在您可以在项目属性中指定copy选项:

   ko.mapping.fromJS(
        [
            { 'qty': 1, 'inner': { 'name': 'thing'} },
            { 'qty': 2, 'inner': { 'name': 'stuff'} }
        ],
        {
            create: function (options) {
                return ko.mapping.fromJS(options.data, {
                    copy: ['inner.name']
                })
            }
        },
        self.slots);

演示JSFiddle.