1

我有一个具有嵌套属性的复杂对象,这些属性从 null 切换为实际填充的对象。我可以通过 ko.mapping.fromJSON 第一次很好地映射所有内容。但是,当一个事件导致发生后续映射时,属性变为 null 并且其他属性获取值时,映射会变得疯狂:

http://jsfiddle.net/L5sgW/51

当“更新!” 单击按钮会触发警报('1')并显示“Test2”。但是,单击“更新!” 再次并 alert('2') 触发,但文本不会改变。有任何想法吗?

html:

<p> <span>Name:</span>
    <span data-bind="text: IntroData ? IntroData.Name : TempData.Name"></span>
    <button id="update" data-bind="click: Update">Update!</button>
</p>

javascript:

var ViewModel = function (data) {
    var me = this;
    ko.mapping.fromJS(data, {}, me);

    me.Update = function () {
        if (me.Index() == '0' || me.Index() == '2') {
            alert('1');
            ko.mapping.fromJS(stuff2, {}, me);
        } else {
            alert('2');
            ko.mapping.fromJS(stuff3, {}, me);
        }
    };

    return me;
};

var stuff = {
    Index: '0',
    IntroData: {
        Name: 'Test'
    },
    TempData: null

};

var stuff2 = {
    Index: '1',
    IntroData: {
        Name: 'Test2'
    },
    TempData: {
        Name: 'Temp2'
    }
};

var stuff3 = {
    Index: '2',
    IntroData: null,
    TempData: {
        Name: 'Temp3'
    }
};

window.viewModel = ko.mapping.fromJS(new ViewModel(stuff));
ko.applyBindings(window.viewModel);
4

1 回答 1

0

您在 stuff 和 stuff3 中为 IntroData 和 TempData 提供了不同的形状。

1/ 当 ko.mapping.fromJS 解释 TempData: null 时,会产生一个 ko.observable(null)。2/ 当 ko.mapping.fromJS 解释 TempData: { Name: 'Temp3' } 时,它将产生一个带有成员 'Name' 的对象,它是一个 ko.observable('Temp3')。

例如,东西:

    > ko.mapping.fromJS({ Index: '0', IntroData: { Name: 'Test' }, TempData: null }, {});

    Object {Index: function, IntroData: Object, TempData: function, __ko_mapping__: Object}
      Index: function observable() {
      IntroData: Object
        Name: function observable() {
        __proto__: Object
      TempData: function observable() {
      __ko_mapping__: Object
      __proto__: Object

还有东西2:

    > ko.mapping.fromJS({ Index: '1', IntroData: { Name: 'Test2' }, TempData: { Name: 'Temp2' } }, {});

    Object {Index: function, IntroData: Object, TempData: Object, __ko_mapping__: Object}
      Index: function observable() {
      IntroData: Object
        Name: function observable() {
        __proto__: Object
      TempData: Object
        Name: function observable() {
        __proto__: Object
      __ko_mapping__: Object
      __proto__: Object

请注意,TempData 是 stuff2 的映射对象中的一个函数(可观察),但在 stuff2 的映射对象中是一个具有子属性“名称”的对象。

那么为什么这不起作用呢?您的绑定指定:

    text: IntroData ? IntroData.Name : TempData.Name

问题是 IntroData永远不会为 null,而且永远是“真实的”。(它要么是一个对象,要么是一个可观察对象。在任何一种情况下,都不是 null。)那么该怎么办呢?好吧,我们可以使定义形状相似,以便 ko.mapping 正确更新值。我将您的绑定修改为:

    text: IntroData.Name() ? IntroData.Name : TempData.Name

并将您的对象定义更改为:

    var stuff = {
        Index: '0',
        IntroData: {
            Name: 'Test'
        },
        TempData: {
            Name: null
        }
    };

    var stuff2 = {
        Index: '1',
        IntroData: {
            Name: 'Test2'
        },
        TempData: {
            Name: 'Temp2'
        }
    };

    var stuff3 = {
        Index: '2',
        IntroData: {
            Name: null
        },
        TempData: {
            Name: 'Temp3'
        }
    };

您会看到您的更新按钮现在显示每次点击的更改。看起来你正试图循环通过 stuff -> stuff2 -> stuff3。代码没有这样做,但你不应该发现很难做到这一点。:-)

于 2013-11-14T05:57:40.867 回答