मान लें कि मैं घटक दृश्य के अंदर घोषित एक फ़ंक्शन निष्पादित करना चाहता हूं मॉडल मॉडल को डेटा रीफ्रेश/सेटअप करने के लिए, रूट बदलते ईवेंट का जवाब देने के लिए बाध्य होना चाहिए। यह कैसे संभव होगा?
में component registration documentation आप 4 विभिन्न विकल्पों को देखने के मॉडल प्रदान करने के लिए:
- 1: एक निर्माता समारोह
- 2: एक साझा वस्तु दृष्टान्त
- 3: एक createViewModel कारखाने समारोह
- चौथा: एक एएमडी मॉड्यूल जिसका मान व्यूमोडेल
का वर्णन करता है
वास्तव में, चौथा विकल्प अन्य 3 विकल्पों में से एक को वापस करने के लिए एएमडी मॉड्यूल का उपयोग कर रहा है। तो require
का उपयोग किए बिना या बिना 3 संभावित विकल्प हैं।
यदि आपका एसपीए केवल आपके घटक के एक उदाहरण का उपयोग करेगा, तो आप दूसरे समाधान का उपयोग कर सकते हैं: व्यूमोडेल बनाएं, इसे एक वेरिएबल में स्टोर करें जो हमेशा गुंजाइश में है (उदाहरण के लिए वैश्विक दायरे में या मॉड्यूल के अंदर), और इसका उपयोग करने के लिए घटक पंजीकृत करें।इस तरह, जब घटक रूटिंग ईवेंट द्वारा इंस्टेंस किया जाता है, तो आप वांछित कार्यक्षमता का आह्वान करने के लिए चर के माध्यम से व्यूमोडेल तक पहुंच सकते हैं।
यदि आपके एसपीए में आपके घटक के कई अलग-अलग उदाहरण हो सकते हैं, या आप बस पिछले समाधान का उपयोग नहीं करना चाहते हैं, तो आपको पहले या तीसरे विकल्प का उपयोग करना होगा (इस प्रश्न के बारे में, इससे कोई फर्क नहीं पड़ता) । इस मामले में आप अपने घटक को कॉलबैक फ़ंक्शन पास कर सकते हैं, जो कि कन्स्ट्रक्टर (1 विकल्प) या फैक्ट्री विधि (तीसरा विकल्प) पैरामीटर में उपलब्ध होगा। कन्स्ट्रक्टर (या फैक्ट्री) अपनी कार्यक्षमता का पर्दाफाश करने के लिए इस कॉलबैक का आह्वान कर सकता है। आप कुछ इस तरह लागू कर सकते हैं, लेकिन जरूरी नहीं कि वास्तव में यह पसंद: आपके आवेदन
// Here you'll store the component APIs to access them:
var childrenComponentsApi = {};
// This will be passed as a callback, so that the child component
// can register the API
var registerChildComponentApi = function(api) {
childrenComponentsApi.componentX = api;
};
नोट के मुख्य गुंजाइश में
: यह एक वस्तु जहां कार्यक्षमता ताकि पंजीकृत किया जा सकता है के लिए महत्वपूर्ण है आप संदर्भ
खोना नहीं है ध्यान में रखते हुए:
<div data-bind='component: {
name: 'componentX',
params: { registerApi: registerChildComponentApi, /*other params*/ }
}'></div>
घटकों में दृश्य मॉडल निर्माता (या कारखाना) शरीर:
params.registerApi({ // The callback is available in thereceived params
func1: func1, // register the desired functions
func2: func2});
बाद में, मुख्य दायरे में, अगर आप इस तरह घटक की कार्यक्षमता का उपयोग कर सकते हैं:
childrenComponentsApi.componentX.fun1 (/ * पैरामीटर * /);
यह बिल्कुल काम नहीं कर रहा कोड है, लेकिन मुझे उम्मीद है कि यह आपको एक विचार देता है कि आपको क्या चाहिए।
यह समाधान पूरी तरह से काम करता है अगर एपीआई तुरंत नहीं आती है। मैंने इस कार्यान्वयन का उपयोग किया जब कार्यक्षमता को उपयोगकर्ता की कार्रवाई के लिए बुलाया जाएगा, ताकि मुझे यकीन है कि घटक पहले ही इंस्टॉल हो चुका है।
लेकिन, आपके मामले में, घटक निर्माण असीमित है, इसलिए आपको कार्यान्वयन को संशोधित करना होगा। कम से कम दो संभावित तरीके हैं:
1) registerApi
कार्यान्वयन को बदलने और प्रारंभ करने के लिए इसका उपयोग करना आसान है। कुछ इस तरह:
ViewModels निर्माता में:
params.registerApi({
init: init, // initialization function
func1: func1, // other exposed functionality
func2: func2});
मुख्य गुंजाइश में: के बाद कॉलबैक ग्राहक घटक द्वारा चलाया जाता है
var registerChildComponentApi = function(api) {
childrenComponentsApi.componentX = api;
childrenComponentsApi.componentx.init(/* params*/)
}
इस implementacion init
में कहा जाता है, इसलिए आप सुनिश्चित कर सकते हैं कि घटक उपलब्ध है।
2) एक और जटिल समाधान में वादे का उपयोग करना शामिल है। यदि आपके घटक को तैयार होने के लिए एसिंक्रोनस ऑपरेशंस करने की आवश्यकता है (उदाहरण के लिए AJAX कॉल कर रहे हैं), तो आप इसे सभी खुला एपीआई के अलावा एक वादा वापस कर सकते हैं, ताकि घटक वास्तव में तैयार होने पर वादा को हल कर सके, और मुख्य दायरा चलता है एपीआई कार्यक्षमता केवल जब वादा हल हो गया है।कुछ इस तरह:
दृश्य मॉडल निर्माता में:
params.registerApi({
ready: ready, // promise created and solved by the component
func1: func1, // exposed functionality
func2: func2});
मुख्य गुंजाइश में:
var registerChildComponentApi = function(api) {
childrenComponentsApi.componentX = api;
}
childrenComponentsApi.componentx.ready().then(
childrenComponentsApi.componentx.func1;
);
ये कुछ कार्यान्वयन नमूने हैं, लेकिन वहाँ उन पर कई रूपों हो सकता है। उदाहरण के लिए, यदि आपको घटक व्यूमोडेल के init
फ़ंक्शन को चलाने की आवश्यकता है, तो आप घटक को provideInit
जैसे पैरामीटर की आपूर्ति कर सकते हैं, और घटक के init
को पेज़ करके इसे कॉन्स्टक्टर में चला सकते हैं। कुछ इस तरह:
<div data-bind='component: {
name: 'componentX',
params: { provideInit: provideInit, /*other params*/ }
}'></div>
var proviedInit: function(init) {
init(/* params */);
};
और भूल नहीं है कि यह भी भी पैरामीटर के रूप में observables गुजर और उन्हें मुख्य दायरे से संशोधित करके constructor.Or के लिए सभी आवश्यक मानकों को पारित करके घटक के viewmodel प्रारंभ करने में संभव है।
आखिरी सबसे अच्छी सलाह जो मैं आपको दे सकता हूं वह यह है कि आप registerApi
कार्यक्षमता को सही ढंग से मानकीकृत और दस्तावेज करते हैं, ताकि सभी घटकों को लागू किया जा सके और उसी तरह उपयोग किया जा सके।
जैसा कि मैंने शुरुआत में बताया था, इनमें से कोई भी समाधान सीधे लागू किया जा सकता है, या एएमडी मॉड्यूल का उपयोग करके। अर्थात। आप दृश्य मॉडल कन्स्ट्रक्टर को सीधे (पहला विकल्प) प्रदान करने वाले घटक को पंजीकृत कर सकते हैं, या एएमडी मॉड्यूल के रूप में कन्स्ट्रक्टर को परिभाषित कर सकते हैं और चौथे विकल्प का उपयोग कर सकते हैं।
* "[..] मार्ग मिलान किए गए ईवेंट के लिए रूटिंग लाइब्रेरी हैंडलर को घटक नाम के लिए एक नया मान सेट करने के लिए बनाएं।" * पारस्परिक रूप से अनन्य है: * "[..] घटक दृश्य के अंदर घोषित एक फ़ंक्शन निष्पादित करें मॉडल बाध्य, [..] मार्ग बदल गया घटना बदल गया "*। क्योंकि मार्ग बदलते समय हर बार आपका घटक टूट जाता है। तो आप केवल दो बार मार्ग परिवर्तन पर प्रतिक्रिया कर सकते हैं: कन्स्ट्रक्टर फ़ंक्शन (सेटअप) में, या घटक टियरडाउन से पहले, [कॉलबैक का निपटान करें] में (http://knockoutjs.com/documentation/component-binding.html#disposal-and- स्मृति प्रबंधन)। कम से कम, यह है, इस सेटअप के साथ। – Tyblitz
आप सही हैं, @Tyblitz, मामला यह है कि मैं इस मामले के लिए अपने सेटअप पर आगे विस्तार करने में विफल रहा। असल में, स्पा सेटअप में मैं बात कर रहा हूं, घटक नाम के लिए एक नए मान के लिए सेटर एक अलग नॉकआउट घटक में होता है क्योंकि घटक के विपरीत मैं अपने दृश्य मॉडल के अंदर एक फ़ंक्शन निष्पादित करना चाहता हूं। –
एक ही एचटीएमएल पर, नेविगेशन को संभालने वाला एक घटक (वह घटक जो घटक नाम बदलता है) और नॉकआउट के घटक बाध्यकारी के साथ एक अन्य कंटेनर टैग, जैसे कि प्रश्न की शुरुआत में दिखाया गया स्निपेट। नेविगेशन घटक घटक NameObservable को बदलता है, इसके आधार पर, घटक बाध्यकारी के साथ कंटेनर (इस मामले में एक div) में एक बार में कई अन्य घटकों को इंजेक्शन दिया जाता है। –