2012-02-15 26 views
189

मुझे लगता है कि मेरा आवेदन अब काफी बड़ा हो रहा है, प्रत्येक दृश्य को एक व्यूमोडेल के साथ संभालने के लिए बहुत बड़ा है।नॉकऑटजेएस - एक दृश्य में एकाधिक दृश्य मॉडल

तो मैं सोच रहा हूं कि एकाधिक व्यू मॉडेल बनाने और उन्हें सभी को एक ही दृश्य में लोड करना कितना मुश्किल होगा। एक नोट के साथ कि मुझे एक्स व्यूमोडेल डेटा वाई व्यू मॉडेल डेटा में पास करने में सक्षम होने की आवश्यकता है ताकि व्यक्तिगत व्यू मॉडेल को एक-दूसरे के साथ संवाद करने में सक्षम होना चाहिए या कम से कम एक-दूसरे से अवगत होना चाहिए।

उदाहरण के लिए मैं एक <select> ड्रॉप डाउन है, कि ड्रॉप डाउन चयन एक चयनित राज्य जो मुझे एक अलग ViewModel में एक और अजाक्स कॉल करने के लिए <select> में चयनित आइटम के आईडी पारित करने के लिए अनुमति देता है .... है

एक ही दृश्य में कई व्यूमोडल्स से निपटने के लिए किसी भी बिंदु की सराहना की गई :)

+11

इस प्रश्न पर पहुंचने वाले लोगों के लिए, कृपया स्वीकृत उत्तर के पीछे स्क्रॉल करें। [नॉकआउट अब कई बाध्यकारी संदर्भों का समर्थन करता है] (http://stackoverflow.com/a/11572094/998328)। एक विशाल 'मास्टरVM' की कोई आवश्यकता नहीं है। –

उत्तर

145

यदि उन्हें सभी को एक ही पृष्ठ पर होना आवश्यक है, तो ऐसा करने का एक आसान तरीका यह है कि एक मास्टर व्यू मॉडल जिसमें सरणी (या संपत्ति सूची) अन्य दृश्य मॉडल के।

masterVM = { 
    vmA : new VmA(), 
    vmB : new VmB(), 
    vmC : new VmC(), 
} 

फिर अपने masterVM अन्य संपत्तियों अगर पेज खुद के लिए की जरूरत है, हो सकता है। दृश्य मॉडल के बीच संचार इस स्थिति में मुश्किल नहीं होगा क्योंकि आप masterVM के माध्यम से रिले कर सकते हैं, या आप बाइंडिंग में $parent/$root या कुछ अन्य कस्टम विकल्पों का उपयोग कर सकते हैं।

+2

तो क्या मैं कुछ ऐसा करने में सक्षम हूं: डेटा-बाइंड = "टेक्स्ट: masterVM.vmA", मुझे लगता है कि मैं अभी भी डीओएम तत्व संलग्न के साथ ko.apply बाइंडिंग का उपयोग कर सकता हूं। अनुमान लगाएं कि इसका अर्थ यह भी होगा कि: डेटा-बाइंड = "$ parent.masterVm"? – CLiown

+12

@CLiown आप 'with:' bindging का उपयोग कर सकते हैं, इसलिए आप अपने आप को दोहराएंगे – AlfeG

+4

@CLiown हां, यदि आप मास्टरVM से बंधे हैं तो आप ऐसा कर सकते हैं। जब आप उप दृश्य मॉडल में गोता लगाते हैं तो आप डॉट सिंटैक्स से बचने में मदद के लिए "साथ" बाइंडिंग का भी उपयोग कर सकते हैं। –

3

चेक MultiModels नॉकआउट जे एस के लिए प्लगइन - https://github.com/sergun/Knockout-MultiModels

+6

इसका क्या फायदा है केवल ko.applyBindings (viewModel, document.getElementById ("divName"))? क्या यह सिर्फ वाक्य रचनात्मक चीनी नहीं है? –

+1

@ पाओलो डेल मुंडो यह लाइवक्वायर प्लगइन पर निर्भरता भी जोड़ता है। –

+0

@PaolodelMundo प्लगइन का उद्देश्य व्यूमोडेट्स के सेट का उपयोग करने में सक्षम होना है –

281

नॉकआउट अब कई मॉडल बंधन का समर्थन करता है। ko.applyBindings() विधि वैकल्पिक पैरामीटर लेती है - तत्व और उसके वंशज जो बाध्यकारी सक्रिय किए जाएंगे।

उदाहरण के लिए:

ko.applyBindings(myViewModel, document.getElementById('someElementId')) 

इस आईडी someElementId और उसके वंश के साथ तत्व के सक्रियण प्रतिबंधित करता है। अधिक जानकारी के लिए

documentation देखें।

+68

यदि आप एक jQuery चयनकर्ता का उपयोग करना चाहते हैं, तो आप वास्तविक डीओएम तत्व निर्दिष्ट करने के लिए '[0] 'जोड़ना चाहेंगे jQuery ऑब्जेक्ट) जैसे: 'ko.apply बाइंडिंग्स (myViewModel, $ ('# someElementId') [0])' – MrBoJangles

+2

यह स्वीकार्य उत्तर होना चाहिए। आप अभी भी एक मास्टर ऑब्जेक्ट का उपयोग कर सकते हैं जैसे कि वर्तमान में स्वीकृत उत्तर है, और फिर व्यक्तिगत दृश्य मॉडल को पृष्ठ पर उनके उचित तत्वों से बांधें। यह प्रदर्शन पर बचाएगा, और डेटा-बाइंड के लिए आवश्यक दायरे को सीमित करेगा। –

+0

क्या इस दृष्टिकोण के साथ एक दूसरे को मॉड्यूल को संवाद करना संभव है? यानी मेरे पास TaskVM और NoteVM है। कार्य नोट्स हो सकता है। इसलिए मेरे TaskVM में एक अवलोकन योग्य होना चाहिए अर्थात् नोट्स जिसका प्रकार TaskVM है। क्या आप इस तरह के मामले के लिए एक उदाहरण साझा कर सकते हैं? – ahmet

18

यह एकमात्र दृश्य में बहुत सारे ViewModels के साथ बहुत बड़ी परियोजना को पूरा करने के बाद मेरा जवाब है।

HTML दृश्य

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title></title> 
</head> 
<body> 
    <div id="container1"> 
     <ul> 
      <li >Container1 item</li> 
      <!-- ko foreach: myItems --> 
      <li>Item <span data-bind="text: $data"></span></li> 
      <!-- /ko --> 
     </ul> 
    </div> 

    <div id="container2"> 
     <ul> 
      <li >Container2 item</li> 
      <!-- ko foreach: myItems --> 
       <li>Item <span data-bind="text: $data"></span></li> 
      <!-- /ko --> 
     </ul> 
    </div> 

    <script src="js/jquery-1.11.1.js"></script> 
    <script src="js/knockout-3.0.0.js"></script> 
    <script src="js/DataFunction.js"></script> 
    <script src="js/Container1ViewModel.js"></script> 
    <script src="js/Container2ViewModel.js"></script> 

</body> 
</html> 

इस दृश्य मैं के लिए आईडी = container1 और आईडी = container2 2 दृश्य मॉडल बनाने रहा हूँ दो अलग-अलग जावास्क्रिप्ट फाइलों में लिए।

Container1ViewModel.js

function Container1ViewModel() 
{ 
    var self = this; 
    self.myItems = ko.observableArray(); 
    self.myItems.push("ABC"); 
    self.myItems.push("CDE"); 

} 

Container2ViewModel.js

function Container2ViewModel() { 
    var self = this; 
    self.myItems = ko.observableArray(); 
    self.myItems.push("XYZ"); 
    self.myItems.push("PQR"); 

} 

फिर आप इन 2 ViewModels

var container1VM; 
var container2VM; 

$(document).ready(function() { 

    if ($.isEmptyObject(container1VM)) { 
     container1VM = new Container1ViewModel(); 
     ko.applyBindings(container1VM, document.getElementById("container1")); 
    } 

    if ($.isEmptyObject(container2VM)) { 
     container2VM = new Container2ViewModel(); 
     ko.applyBindings(container2VM, document.getElementById("container2")); 
    } 
}); 

DataFunction.js में के रूप में अलग ViewModels दर्ज कर रहे हैं इस तरह के बाद जोड़ सकते हैं अलग divs के लिए दृश्य संख्या के किसी भी संख्या।लेकिन सुनिश्चित करें कि पंजीकृत div के अंदर एक div के लिए अलग दृश्य मॉडल न बनाएं।

0

हम इसे प्राप्त करने के लिए घटकों का उपयोग करते हैं। https://github.com/EDMdesigner/knobjs

आप कोड में खुदाई, तो आप उस उदाहरण के लिए हम कई स्थानों में घुंडी बटन घटक का पुन: उपयोग देखेंगे: (http://knockoutjs.com/documentation/component-overview.html)

उदाहरण के लिए, हम इस घटक पुस्तकालय हम विकसित कर रहे हैं की है।

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