【问题标题】:Knockout ko.mapping.fromJSON not updating淘汰赛 ko.mapping.fromJSON 未更新
【发布时间】:2013-10-22 20:35:31
【问题描述】:

我有一个具有嵌套属性的复杂对象,这些属性从 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);

【问题讨论】:

    标签: knockout-mapping-plugin


    【解决方案1】:

    您在 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 是 stuff 映射对象中的一个函数(可观察),但在 stuff2 的映射对象中是具有子属性“名称”的对象。

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

        text: IntroData ? IntroData.Name : TempData.Name
    

    问题是 IntroData 从不为空,而且总是“真实”。 (它要么是一个对象,要么是一个可观察对象。在任何一种情况下,都不是 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。代码没有这样做,但你不应该发现很难做到这一点。 :-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-08
      • 2014-10-18
      相关资源
      最近更新 更多