2012-03-09 17 views
6

का उपयोग कर मॉडल को अपडेट/सम्मिलित करें मैं अब कुछ समय से इसे समझने की कोशिश कर रहा हूं। मुझे इस समस्या को हल करने वाली कुछ भी नहीं मिली, लेकिन अगर मैं गलत हूं तो कृपया मुझे सही करें।नॉकआउटजेएस: मैपिंग

समस्या: मेरे पास एक जेएसओएन एपीआई से डेटा है जो एक नेस्टेड सरणी/ऑब्जेक्ट स्ट्रक्चर के साथ आता है। मैं अपने डेटा के साथ मॉडल को शुरू करने के लिए मैपिंग का उपयोग करता हूं। इसे अपडेट करने के लिए, यदि नया डेटा आता है, या मौजूदा डेटा को अपडेट करते हैं, तो मैं मॉडल का विस्तार करना चाहता हूं।

जहां तक ​​मुझे पता चला, मैपिंग विकल्प कुंजी, मेरे लिए यह चाल करना चाहिए, लेकिन मैंने मैपिंग विकल्पों की कार्यक्षमता को गलत समझा होगा।

मैं इस समस्या नीचे उबला हुआ गए इस उदाहरण द्वारा प्रतिनिधित्व किए जाने:

var userMapping = { 
    key: function(item) { 
     return ko.utils.unwrapObservable(item.id); 
    } 
}; 

// JSON call replaced with values 
var viewModel = { 
    users: ko.mapping.fromJS([], userMapping) 
}; 

// Should insert new - new ID? 
ko.mapping.fromJS([{"id":1,"name":"Foo"}, {"id":2,"name":"Bar"}], userMapping, viewModel.users); 

// Should only update ID#1 - same ID? 
ko.mapping.fromJS([{"id":1,"name":"Bat"}], userMapping, viewModel.users); 

// Should insert new - New ID? 
ko.mapping.fromJS([{"id":3,"name":"New"}, {"id":4,"name":"New"}], userMapping, viewModel.users); 

ko.applyBindings(viewModel);​ 

फिडल: http://jsfiddle.net/mikaelbr/gDjA7/

आप देख सकते हैं, पहली पंक्ति डेटा सम्मिलित करता है। सब अच्छा। लेकिन जब मैं अद्यतन करने का प्रयास करता हूं, तो यह सामग्री को प्रतिस्थापित करता है। तीसरे मैपिंग के लिए वही; यह इसे विस्तारित करने के बजाय, सामग्री को प्रतिस्थापित करता है।

क्या मैं इसे गलत इस्तेमाल कर रहा हूं? क्या मैपिंग का उपयोग करने से पहले सामग्री को मैन्युअल रूप से विस्तारित करने का प्रयास करना चाहिए?

संपादित करें समाधान:
मैं एक दूसरे सहायक सरणी सभी मौजूदा मॉडलों के भंडारण होने से इस मामले को हल किया। नए डेटा पर मैंने इस सरणी को बढ़ाया, और संचित वस्तुओं को रखने के लिए दृश्य मॉडल को अपडेट किया।

अपडेट पर (मेरे मामले में एक वेबसाकेट संदेश), मैंने मॉडल के माध्यम से looped, प्रश्न में आइटम की सामग्री बदल दी, और इस्तेमाल मूल्य मूल्य HasMutated() नॉकआउट lib में परिवर्तित मूल्य की सूचना देने के लिए।

उत्तर

4

अपने उदाहरण कोड को देख से मानचित्रण प्लगइन बिल्कुल बर्ताव कर रही है के रूप में मैं इसे करने के लिए उम्मीद करेंगे। जब आप संग्रह पर fromJS पर कॉल करते हैं तो आप मैपिंग प्लगइन को प्रभावी ढंग से बता रहे हैं कि यह उस संग्रह की नई सामग्री है। उदाहरण के लिए:

दूसरी पंक्ति पर, यह कैसे पता चलेगा कि आप अपडेट कर रहे थे या आपने आईडी को हटा दिया था: 2?

मुझे एक उपयुक्त विधि का कोई उल्लेख नहीं मिल रहा है जो डेटा को केवल एक अद्यतन के रूप में मानता है, हालांकि आप एक जोड़ सकते हैं। मैप किए गए सरणी कुछ उपयोगी तरीकों के साथ आती हैं जैसे कि mappedIndexOf विशेष वस्तुओं को ढूंढने में आपकी सहायता के लिए। यदि आपको अपडेट डेटा सेट प्राप्त होता है तो बस इसके माध्यम से लूप करें, आइटम ढूंढें और इसे उस मैपिंग के साथ अपडेट करें। फ्रॉम जेएस उस विशेष आइटम पर कॉल करें। इसे आसानी से पुन: प्रयोज्य विधि में सामान्यीकृत किया जा सकता है।

+0

हां। यह कम या कम है कि मैंने इसे कैसे हल किया। – mikaelb

+0

इस पर कोई विचार: http://stackoverflow.com/questions/20397054/knockout-js-mapping-keys-and-kendo-ui-grid – jtromans

0

हां, आपको पहले सभी डेटा को सूची या सरणी में एकत्र करना चाहिए और फिर उस सूची में मैपिंग लागू करना चाहिए। अन्यथा आप अपने दृश्य मॉडल में मानों को ओवरराइट करने जा रहे हैं।

1

आप मौजूदा मानों को अपडेट करने के लिए ko.mapping.updateFromJS() का उपयोग कर सकते हैं। हालांकि, यह नए मान नहीं जोड़ता है ताकि यह आपके उदाहरण में एक समस्या होगी। अधिक जानकारी के लिए नीचे दिए गए लिंक पर नज़र डालें।

Using updateFromJS is replacing values when it should be adding them

+4

updateFromJS() विधि अगस्त 2011 में हटा दिया गया था https://github.com/SteveSanderson/knockout.mapping/commit/bff3c1864a5fd45289933b35de1ef70af4aed6b5 – mikaelb

+0

+1 @mikaelb - मुझे लगता है कि नहीं पता था। जानकारी के लिए धन्यवाद। –

संबंधित मुद्दे