2013-10-22 2 views
1

null이 아닌 실제 채워진 개체로 전환되는 중첩 된 속성이있는 복잡한 개체가 있습니다. 처음에는 ko.mapping.fromJSON을 통해 모든 것을 잘 맵핑 할 수 있습니다. 이벤트 속성이 null이 될 경우 발생하는 후속 매핑을 유발하고 다른 값을 얻을 때 매핑 미친 간다 :녹아웃 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> 

자바 스크립트 : 당신은 물건과 stuff3에 IntroData 및 TempData에 대해 서로 다른 모양을 제공 한

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

.

1/ko.mapping.fromJS가 TempData : null을 해석하면 ko.observable (null)이 생성됩니다. 2/ko.mapping.fromJS가 TempData를 해석 할 때 : {Name : 'Temp3'} ko.observable ('Temp3') 멤버 'Name'을 가진 객체를 생성합니다. 예를 들어

, 재료 :

> 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"입니다. (그것은 객체이거나 관측 가능합니다. 두 경우 모두 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을 순환하려고하는 것처럼 보입니다. 이 코드는 그렇게하지 않지만, 그런 일이 일어나지 않도록해야합니다. :-)