2013-10-22 42 views
1

我有一個嵌套屬性的複雜對象,它從null切換爲實際填充的對象。我可以通過ko.mapping.fromJSON首次映射一切。但是,當一個事件導致隨後的映射發生在那裏的屬性成爲空,別人得到的值映射發瘋:Knockout ko.mapping.fromJSON不更新

http://jsfiddle.net/L5sgW/51

當「更新!」按鈕被點擊時,警報('1')被觸發並顯示「Test2」。但是,請點擊「更新!」再次提醒('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); 

回答

0

你的東西,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 

而且stuff2:

> 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的映射對象中。

那麼,爲什麼這不起作用?您綁定指定:

text: IntroData ? IntroData.Name : TempData.Name 

問題是IntroData是不能爲null,始終以 「truthy」。 (它可以是一個對象,也可以是一個可觀察對象,不管是哪種情況,都不爲空)。那麼該怎麼做?那麼,我們可以使定義形狀相似,以便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' 
     } 
    }; 

,你會看到你的更新,按鈕顯示每次點擊的變化。它看起來像你試圖循環的東西 - > stuff2 - > stuff3。代碼沒有這樣做,但你不應該覺得難以做到這一點。 :-)