2012-09-08 14 views
21

द्वारा बनाई गई नॉकआउट ऑब्जेक्ट की गहरी प्रतिलिपि कैसे बना सकता हूं, यह मेरा परिदृश्य है। मैं अपने लिए एक अवलोकन योग्य दृश्य पदानुक्रम बनाने के लिए नॉकआउट मैपिंग प्लगइन का उपयोग कर रहा हूं। मेरे पदानुक्रम ने इसमें तत्वों को घोंसला दिया है। पदानुक्रम में किसी विशेष बिंदु पर मैं अवलोकन योग्य में उस तत्व की एक नई खाली प्रतिलिपि डालने के लिए एक जोड़ें बटन डालना चाहता हूं। समस्या यह है कि मैं सिर्फ कुछ भी नहीं कह सकता Arr.push (नया MyObject())।मैपिंग प्लगइन

चूंकि मानचित्रण प्लगइन ने वास्तव में मेरे लिए संपूर्ण पदानुक्रम बनाया है, इसलिए मेरे पास "MyObject" तक पहुंच नहीं है। तो ऐसा लगता है कि एक नई चीज डालने के लिए मैं एकमात्र चीज कर सकता हूं, पिछली वस्तु को देखने और इसे कॉपी करने के लिए। मैंने ko.utils.extend फ़ंक्शन का प्रयास किया, लेकिन ऐसा लगता है कि यह वास्तविक क्लोन नहीं बना रहा है। यह मुझे एक ऑब्जेक्ट वापस देता है, लेकिन जब मैं उस ऑब्जेक्ट को अपडेट करता हूं तब भी वह उस मूल ऑब्जेक्ट को प्रभावित करता है जिसकी प्रतिलिपि बनाई गई थी।

jsfiddle example

उत्तर

37

मानचित्रण सेटिंग में इस सेट अप के लिए एक रास्ता हो सकती है, लेकिन मैं काफी बस अभी तक कि समझ से बाहर नहीं कर पा रहा।

इस बीच, आप ऑब्जेक्ट को अनैप कर सकते हैं और इसे वापस मैप कर सकते हैं ताकि आप अनिवार्य रूप से एक प्रति बना रहे हों।

var newJob = ko.mapping.fromJS(ko.mapping.toJS(job)); 

यह किसी भी अन्य पुस्तकालय, "deserialize" और "serialize" की तरह फिर से करने का सबसे आसान तरीका होगा।


मैपिंग विकल्पों का उपयोग करके ऐसा करने के लिए मैं एक अच्छा तरीका ढूंढ रहा था और एक रास्ता खोज रहा था।

डिफ़ॉल्ट रूप से, मैपिंग प्लगइन स्रोत ऑब्जेक्ट से देखने योग्य उदाहरण लेगा और लक्ष्य ऑब्जेक्ट में उसी उदाहरण का उपयोग करेगा। तो असल में, दोनों उदाहरण एक ही अवलोकन (बग?) साझा करेंगे। हमें जो करना था वह प्रत्येक संपत्ति के लिए एक नया अवलोकन योग्य था और मूल्यों की प्रतिलिपि बना रहा था।

सौभाग्य से, किसी ऑब्जेक्ट के प्रत्येक गुण को मैप करने के लिए एक आसान उपयोगिता फ़ंक्शन है। इसके बाद हम मूल्यों की प्रतियों के साथ शुरू किए गए हमारे नए अवलोकन योग्य उदाहरण बना सकते हैं।

// Deep copy 
var options = { 
    create: function (options) { 
     // map each of the properties 
     return ko.mapping.visitModel(options.data, function (value) { 
      // create new instances of observables initialized to the same value 
      if (ko.isObservable(value)) { // may want to handle more cases 
       return ko.observable(value); 
      } 
      return value; 
     }); 
    } 
}; 
var newJob = ko.mapping.fromJS(job, options); 

ध्यान दें कि यह एक उथले प्रति रहेगी, तो आप शायद रिकर्सिवली वस्तुओं मैप करने के लिए आप एक गहरी कॉपी चाहते हैं तो होगा। हालांकि यह आपके उदाहरण में समस्या को ठीक करेगा।

+0

धन्यवाद! ऐसा लगता है कि काम कर रहा है। – emirhosseini

+0

हालांकि मुझे अभी भी आश्चर्य है कि नॉकआउट में एक ऑब्जेक्ट का वास्तविक क्लोन बनाने के लिए बेहतर तरीका है जिसमें अवलोकन है। यह वास्तव में एक मुद्दा नहीं होगा यदि मैं मैपिंग प्लगइन का उपयोग नहीं कर रहा था तब से मैं प्रत्येक बच्चे को ऑब्जेक्ट बनाने वाला व्यक्ति बनूंगा और मैं प्रतिलिपि बनाने की कोशिश करने के बजाए सीधे एक से सीधे नया कर सकता हूं ... – emirhosseini

+0

आह, मैं समझ गया। मैं अपने निष्कर्षों के बारे में एक लंबी टिप्पणी छोड़ने और लिखने की प्रक्रिया में था ... तब मेरे पास एक रहस्योद्घाटन था और इसे समझ लिया गया। –

6
ko.utils.clone = function (obj) { 
    var target = new obj.constructor(); 
    for (var prop in obj) { 
     var propVal = obj[prop]; 
     if (ko.isObservable(propVal)) { 
      var val = propVal(); 
      if ($.type(val) == 'object') { 
       target[prop] = ko.utils.clone(val); 
       continue; 
      } 
      target[prop](val); 
     } 
    } 
    return target; 
}; 

यहां मेरा समाधान है, उम्मीद है कि यह मदद करता है। इस कोड में, obj आपका दृश्य मॉडल ऑब्जेक्ट होगा।

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