हब पर
नॉकआउट.जेएस पुस्तकालय के बारे में बहुत कुछ नहीं लिखा गया है, लेकिन
कुछ है (और निश्चित रूप से
आधिकारिक साइट पर एक
आधिकारिक ट्यूटोरियल और अन्य सामग्री है और अंग्रेजी में एक अच्छा संसाधन है।
नॉरमे.नेट , जिनके लेख मैं अनुवाद कर सकते हैं अगर मांग है । यह लेख जावास्क्रिप्ट और नॉकआउट पर लेखों की एक श्रृंखला में विकसित हो सकता है, अगर यूएफओ मुझे अपहरण नहीं करता है।
प्रारंभ में, मैंने पहले से ही नॉकआउट और एमवीएमएम से परिचित लोगों के लिए सामग्री तैयार की थी, लेकिन अन्य लेखों की टिप्पणियों में मुझे यह बताने के लिए कहा गया था कि डमी के लिए नॉकआउट कैसे तैयार किया जाए। मुझे लगता है कि आपने पहले ही हब्र पर नॉकआउट के बारे में लेख पढ़ लिया है। चलो चलें!
मुझे नॉकआउट.जेएस की आवश्यकता क्यों है?
- JSON जैसी ऑब्जेक्ट (मॉडल) से डेटा के साथ इंटरफ़ेस को आसानी से भरने में सक्षम होने के लिए:
var ViewModel = { attribute1: ”Hello”, attribute2: ”world!”, };
लेआउट:
<div> <span data-bind=”text: attribute1”></span> <span data-bind=”text: attribute2”></span> </div>
बंधन:
ko.applyBindings( ViewModel );
परिणाम:
<div> <span data-bind=”text: attribute1”>Hello</span> <span data-bind=”text: attribute2”>world!</span> </div>
लेकिन इस तरह के बंधन का उपयोग अक्सर नहीं किया जाता है, क्योंकि जब मॉडल बदलता है, तो डोम नहीं बदलता है, और इसके विपरीत।
- एक दो-तरफ़ा अवलोकन इंटरफ़ेस और मॉडल बाइंडिंग बनाएं, अर्थात। वास्तविक समय में, इंटरफ़ेस तब बदला जाएगा जब मॉडल बदलता है, और जब इंटरफ़ेस बदलता है (रूपों में पाठ दर्ज करते समय एक कामकाजी उदाहरण )। एक चेतावनी है: इनपुट फ़ील्ड में, मॉडल को केवल ऑनब्लर इवेंट (एलिमेंट से फोकस हटाएं) के साथ अपडेट किया जाएगा, इस स्थिति को
input
इवेंट की सदस्यता लेने से ठीक किया जा सकता है, और मैन्युअल रूप से मॉडल को तदनुसार अपडेट कर सकते हैं। Jsfiddle उदाहरण । उपयोगकर्ता m_z ने valueUpdate: 'input'
( उदाहरण ) का उपयोग करके मॉडल को अपडेट करने के लिए अधिक सुविधाजनक विकल्प valueUpdate: 'input'
। - वैकल्पिक रूप से मॉडल परिवर्तनों की सदस्यता लें। प्रलेखन से कोड:
myViewModel.personName.subscribe(function(newValue) { alert(" : " + newValue); });
परिवर्तनों से सदस्यता समाप्त करें:
var subscription = myViewModel.personName.subscribe(function(newValue) { });
डेटा-बाइंड विशेषता और बाइंडिंग क्या है?
यह विशेषता एक json ऑब्जेक्ट के समान है, यह हमें मौजूदा DOM नोड में डेटा और ईवेंट हैंडलर को बांधने की अनुमति देता है। Knockout.js इस विशेषता को पार्स करता है और जावास्क्रिप्ट एक्सप्रेशन (
डॉक में विस्तार से वर्णित) निष्पादित करता है। यह निर्माण स्थानांतरित डेटा मॉडल के संदर्भ में लॉन्च किया गया है। तदनुसार, जावास्क्रिप्ट कोड के संदर्भ में विशेषता सिंटैक्स सही होना चाहिए।
Knockout.js मानक बाइंडिंग का एक सेट प्रदान करता है जो आपको जादुई चीज़ों को बनाने, शैलियों, सामग्री, हैंडलर और बहुत कुछ संपादित करने की अनुमति देता है। इसके अलावा, आप अपनी खुद की बाइंडिंग लिख सकते हैं, यह अच्छी तरह से फिर से
डॉक में वर्णित है।
यह इस बात का वर्णन करता है कि आपको नॉकआउट की आवश्यकता क्यों है, आप सब कुछ जानते हैं कि किस साइट पर कुछ चीजों को ढूंढना और आगे बढ़ना है जो एक शुरुआत के लिए स्पष्ट नहीं हैं।
अवलोकन योग्य कार्य करें
मान लीजिए कि आपको गतिशील रूप से उस सरणी को बदलने की आवश्यकता है जिसमें कुछ हैंडलर (या इंटरफ़ेस) सब्सक्राइब किए गए हैं। उदाहरण के लिए, आपको सर्वर से डेटा का एक नया बैच मिला और एक चक्र में उन्हें सरणी में जोड़ें।
यदि आप माथे में सब कुछ करते हैं, तो परिवर्तन हैंडलर आपके द्वारा जोड़े गए कई तत्वों के रूप में कई बार काम करेगा। और यह प्रदर्शन को प्रभावित करेगा। उदाहरण
knockmeout.net से लिया गया है
आपको यह नहीं करना है:
var items = ko.observableArray([]); for (var i = 0, j = newData.length; i < j; i++) { items.push( newData[i] ); }
यह बेहतर है:
var items = ko.observableArray([]);
Jsfiddle पर पूर्ण उदाहरण।
Stackoverflow पर टिप्पणी भी इस तरह के एक समारोह की सिफारिश:
ko.observableArray.fn.pushAll = function(valuesToPush) { var underlyingArray = this(); this.valueWillMutate(); ko.utils.arrayPushAll(underlyingArray, valuesToPush); this.valueHasMutated(); return this; };
टेम्पलेट्स
मुख्य रूप से डेटा के साथ इंटरफ़ेस को भरने के लिए प्रोजेक्ट में नॉकआउट। जेएस की आवश्यकता है। इसके लिए सबसे आम परिदृश्य JSON डेटा और रेंडरिंग के साथ सर्वर से AJAX अनुरोध प्राप्त कर रहा है, अर्थात। पृष्ठ को फिर से लोड किए बिना सामग्री अपडेट करना।
ऐसा करने के लिए, हमें उस पृष्ठ के टुकड़े की आवश्यकता है जिसे हम इंटरफ़ेस में बदल सकते हैं और डेटा से भर सकते हैं - अर्थात। हमें विभिन्न डेटा के लिए टेम्प्लेट चाहिए। Knockout.js विभिन्न प्रकार के टेम्प्लेट (jQuery.tmpl, underscore, native) के साथ काम कर सकते हैं - चलो बाद वाले पर रहते हैं (हालांकि हमें अपना लिखने की अनुमति भी है)।
गैर-देशी टेम्पलेट इंजन इसके अंदर कुछ बाइंडिंग के उपयोग का समर्थन नहीं करते हैं (विशेष रूप से, बहुत अच्छा
है , जो टेम्पलेट के लिए मॉडल संदर्भ को बदल देता है)।
इसलिए, कुछ मामलों में, मैं नॉकआउट से देशी टेम्पलेट इंजन का उपयोग करना चाहता हूं। ऐसा करने के लिए, विकल्पों में से आपको
templateEngine: ko.nativeTemplateEngine.instance
पास करना होगा
templateEngine: ko.nativeTemplateEngine.instance
। क्या दिलचस्प है (और प्रलेखन में नहीं कहा गया है) यह है कि इस पैरामीटर को टेम्पलेट बंधन में भी पारित किया जा सकता है।
प्रोग्रामेटिक रूप से टेम्प्लेट प्रस्तुत करने के लिए, कमांड का उपयोग करें:
ko.renderTemplate(templateName, viewModel, options, domNodeToRender);
उदाहरण के लिए, _create () पद्धति में jquery विजेट बनाने वाले टेम्प्लेट का उपयोग करते समय इस कमांड को आसानी से कहा जाता है, और यह इस तरह से किया जाता है:
ko.renderTemplate('templateName', this, { templateEngine: ko.nativeTemplateEngine.instance }, this.element.get(0) );
इसके अलावा, टेम्पलेट को दूसरे टेम्पलेट से कॉल करने के लिए, मानक
टेम्पलेट बाइंडिंग का उपयोग किया जाता है:
<ul data-bind="template: { name: templateName, data: viewModel, templateEngine: ko.nativeTemplateEngine.instance }"></ul>
templateName
-
templateName
का नाम, व्यवहार में, यह
id
ब्लॉक की
id
है जिसमें टेम्पलेट वाला लेआउट स्थित है:
<script type="text/html" id="templateName"> <h3 data-bind="text: name"></h3> <p>Credits: <span data-bind="text: credits"></span></p> </script>
उसी समय, टेम्पलेट इंजन "इनहेरिट" नहीं किया जाता है जब नेस्टेड टेम्पलेट कहा जाता है - यदि हम टेम्पलेट को देशी टेम्पलेट इंजन द्वारा संसाधित टेम्पलेट से कहते हैं, तो आंतरिक टेम्पलेट (यदि आप टेम्पलेट इंजन को जबरन निर्दिष्ट नहीं करते हैं) तब भी डिफ़ॉल्ट टेम्पलेट इंजन का उपयोग करता है (उदाहरण के लिए, jQuery.tmpl, यदि एक जुड़ा हुआ था) परियोजना में)।
इसलिए, यदि अन्य टेम्पलेट इंजन प्रोजेक्ट में उपयोग किए जाते हैं, और आप मूल निवासी का उपयोग करना चाहते हैं, तो इंजन को हर बार निर्दिष्ट किया जाना चाहिए। लेकिन यह सुविधा हमें एक साथ नेस्टेड टेम्पलेट्स के लिए विभिन्न टेम्पलेट इंजन का उपयोग करने की अनुमति देती है।
जड़ तत्व के बिना टेम्पलेट
कभी-कभी आप टेम्पलेट की सामग्री के लिए एक अतिरिक्त कंटेनर नहीं बनाना चाहते हैं, ताकि यह पता न चले कि इसमें केवल एक तत्व एम्बेडेड है। टेम्पलेट में, बाइंडिंग या शैलियों के कारण एक तत्व आवश्यक हो सकता है।
इस स्थिति में, नॉकआउट के लिए मानक विकल्प उपयुक्त है (आभासी तत्व):
यद्यपि यह प्रलेखन में वर्णित नहीं है।
टेम्पलेट्स में डिबगिंग
सबसे आम प्रोग्रामिंग ऑपरेशन डीबगिंग है (हालांकि कुछ बहस कर सकते हैं)। नीचे दी गई विधि आपको कॉमा ऑपरेटर और ग्रुपिंग ऑपरेटर (
इन ऑपरेटरों के बारे में अधिक ) का उपयोग करके कंसोल में संदेश प्रदर्शित करने की अनुमति देगा।
<div data-bind="html: ( console.log( details ), details )"></div>
के साथ और foreach के साथ बदलते संदर्भ - ख़तरा
मान लीजिए हमारे पास एक सरणी है जो उन पंक्तियों को संग्रहीत करती है जिन्हें हम ट्रैक करना चाहते हैं।
सरणी आरंभीकरण कुछ इस तरह दिखता है:
var obArray = ko.observableArray([ ko.observable(“Task One”), ko.observable(“Task Two”), ko.observable(“Task Three”) ]);
और हम इसे संपादित करने के लिए इनपुट से मिलकर एक फॉर्म प्रदर्शित करना चाहते हैं:
<div data-bind=”foreach: obArray”> <input type=”text” data-bind=”value: $data”/> </div>
इस तरह के रिकॉर्ड में, टेक्स्ट फ़ील्ड दो दिशाओं में काम नहीं करेंगे - फ़ील्ड में टेक्स्ट बदलने से एरे के तत्वों पर कोई प्रभाव नहीं पड़ेगा, लेकिन एरे के तत्वों को बदलने से टेक्स्ट फ़ील्ड की सामग्री प्रभावित होगी।
Jsfiddle उदाहरण ।
कारण यह है कि उपरोक्त पैटर्न अनिवार्य रूप से निम्नलिखित के बराबर है:
<div data-bind=”foreach: obArray”> <input type=”text” data-bind=”value: $data”/> </div>
with: $data
- यह वह जगह है जहाँ
$data: unwrapObservable( $data )
का "
$data: unwrapObservable( $data )
" होता है
$data: unwrapObservable( $data )
इसलिए होता है ताकि टेम्प्लेट के अंदर
$data.somefield
तरह कॉल हो। लेकिन यह अनपैकिंग विकल्प के बजाय
$data
अंदर - इसका मूल्य। इस समस्या के आसपास कैसे पहुँचें - बिना सोचे समझे। लेकिन यूजर
लेगा ने एक रैपर ऑब्जेक्ट (
उदाहरण ) बनाने के विकल्प का उपयोग करने का
सुझाव दिया , यदि आपके पास कई फ़ील्ड हैं, तो यह विधि उचित है और काम करेगी।
पाठ संपादकों के साथ काम करें
हमने पहले ही सीखा है कि एक ही नाम की वास्तविक समय की घटना का उपयोग करके इनपुट से मूल्य कैसे प्राप्त किया जाए, लेकिन संपादकों के बारे में क्या है जहां सामग्री html तत्व है? हम
MutationObserver और उसके बाद से उपयोग करेंगे यह एप्पी हर जगह काम नहीं करता है, हम स्वयं को अन्य DOM ईवेंट के साथ बीमा कर सकते हैं और बहुत क्रॉस-ब्राउजर नहीं लिख सकते (आधुनिक ब्राउज़र ठीक काम करते हैं) कोड जो आपके पसंदीदा संपादक में बनाया जा सकता है:
मैं इस फ़ंक्शन का उपयोग किसी एक प्रोजेक्ट में मॉडल को अपडेट करने के लिए करता हूं, जो कि एक अच्छे
संपादक का उपयोग करता है, अगर किसी को प्लग-इन के रूप में इस कोड की आवश्यकता
होती है , तो मैं इसे लिखकर
जीथब पर रख सकता हूं।
निष्कर्ष
लेख सामान्य आकार का निकला, लेकिन सामग्री अभी भी बनी हुई है - पेड़ों के साथ काम करते हुए, अपने स्वयं के बाइंडिंग, jQuery के नॉकआउट विजेट और कुछ अन्य चालें और उदाहरण लिख रहे हैं। एक आरोप के साथ वोट दें, टिप्पणी करें, त्रुटियों को इंगित करें।
वर्तनी और विराम चिह्न में त्रुटियों के लिए, मैं पीएम से पूछता हूं।