KnockOutJS - एक दृश्य में कई ViewModels


201

मैं सोच रहा हूं कि मेरा आवेदन अब काफी बड़ा हो रहा है, प्रत्येक दृश्य को एक ही ViewModel के साथ संभालने के लिए बहुत बड़ा है।

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

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

एक नजर में कई ViewModels के साथ काम करने पर कोई बिंदु की सराहना की :)


12
इस प्रश्न पर पहुंचने वालों के लिए, कृपया स्वीकृत उत्तर को स्क्रॉल करें। नॉकआउट अब कई बाध्यकारी संदर्भों का समर्थन करता है । किसी विशाल की आवश्यकता नहीं है masterVM
कैरी केंडल

जवाबों:


150

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

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

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


2
तो क्या मैं कुछ ऐसा कर पाऊंगा जैसे: data-bind = "text: masterVM.vmA", मुझे लगता है कि मैं अभी भी ko.applyBindings का उपयोग DOM तत्व के साथ कर सकता हूं। मान लें कि मेरा मतलब यह भी हो सकता है: डेटा-बाइंड = "$ parent.masterVm"?
CLIown

12
@ क्लब आप बाइंडिंग का उपयोग कर सकते हैं with:, इसलिए आप अपने आप को नहीं दोहराएंगे
एल्फेग

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

1
मुझे लगता है कि यह दृष्टिकोण एक बहुत ही प्रतिबंधक है ... अब मेरे मामले में मैं ASP.Net MVC4 का उपयोग कर रहा हूं, क्योंकि यह अपने स्वयं के ViewModels वाले आंशिक विचारों में मदद नहीं करेगा, और आंशिक / सामग्री अनुभाग, एक दूसरे के साथ हस्तक्षेप नहीं करना चाहिए , और सशर्त प्रतिपादन के कारण इस दृष्टिकोण का उपयोग करना वास्तव में कठिन होगा।
भुवि

1
@bhuvin का उपयोग कर <! - ko stopBinding: true -> आपको उस मल्टीपल व्यू मॉडल और आंशिक व्यू सेक्शन में मदद करेगा। अधिक जानकारी के लिए knockmeout.net/2012/05/quick-tip-skip-binding.html देखें ।
माइकेल फेलिक्स

285

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

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

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

यह आईडी someElementIdऔर उसके वंश के साथ सक्रियण को प्रतिबंधित करता है ।

अधिक विवरण के लिए प्रलेखन देखें ।


72
यदि आप एक jQuery चयनकर्ता का उपयोग करना चाहते हैं, तो आप [0]एक वास्तविक DOM तत्व (jQuery ऑब्जेक्ट के बजाय) को निर्दिष्ट करना चाहते हैं, जैसे:ko.applyBindings(myViewModel, $('#someElementId')[0])
MrBoJangles

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

क्या इस दृष्टिकोण के साथ एक-दूसरे को देखने के लिए संवाद करना संभव है? यानी मेरे पास टास्कवीएम और नोटवीएम है। टास्क में नोट्स हो सकते हैं। इसलिए मेरे टास्कवीएम के पास एक पर्यवेक्षित नाम होना चाहिए जिसका नाम है टास्कवीएम। क्या आप उस तरह के मामले के लिए एक उदाहरण साझा कर सकते हैं?
आह्मट

एक नए प्रश्न में वीएम के बीच संचार के बारे में पूछना सबसे अच्छा है।
रिचर्ड नेलज़िनस्की

21

एक दृश्य में बहुत सारे 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>

इस दृश्य के लिए मैं दो अलग-अलग जावास्क्रिप्ट फ़ाइलों में आईडी = कंटेनर 1 और आईडी = कंटेनर 2 के लिए 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 व्यूअमॉडल को डाटाफंक्शन.जेएस में अलग व्यूमॉडल के रूप में पंजीकृत किया जाता है

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"));
    }
});

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


क्या डोम के अलग-अलग तत्व होने के बजाय इसे दूसरे के अंदर देखने का काम करना संभव है?
UserEsp

4

नॉकआउट जेएस के लिए मल्टीमॉडल प्लगइन की जाँच करें - https://github.com/sergun/Knockout-MultiModels


6
इससे क्या फायदा होता है, बस ko.applyBindings (viewModel, document.getElementById ("divName"))? क्या यह सिंटैक्टिक शुगर नहीं है?
पाओलो डेल मुंडो

1
@Paolo del Mundo यह LiveQuery प्लगइन पर निर्भरता भी जोड़ता है।
लार्स सिरप ब्रिंक नीलसन

@PaolodelMundo प्लगइन का उद्देश्य निर्णायक तरीके से दृश्यमॉडल के सेट का उपयोग करने में सक्षम होना है
सर्गेई ज़्वेज़दीन

1

इसे प्राप्त करने के लिए हम घटकों का उपयोग करते हैं। ( http://knockoutjs.com/documentation/component-overview.html )

उदाहरण के लिए, हमारे पास यह घटक पुस्तकालय है जिसे हम विकसित कर रहे हैं: https://github.com/EDMdesigner/knobjs

यदि आप कोड में खुदाई करते हैं, तो आप देखेंगे कि उदाहरण के लिए हम कई स्थानों पर नॉब-बटन घटक का पुन: उपयोग करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.