2011-11-26 19 views
33

जब मैं do में किसी भी नए तत्व को ko.applyBindings() के बाद इंजेक्ट करता हूं; कहा जाता था, तो नॉकआउट इन नए तत्वों को पहचान नहीं पाएगा। मैं समझ सकता हूं कि यह क्यों हो रहा है - वे नॉकआउट द्वारा अनुक्रमित नहीं हैं।knockout.js: बाइंडिंग अपडेट करें?

तो, मैंने पहले सोचा था कि यह मेरे नए तत्व जोड़ने के बाद, फिर से ko.applyBindings() को कॉल करके हल किया जाएगा, लेकिन फिर मुझे एहसास हुआ कि प्रत्येक ko.apply बाइंडिंग्स() कॉल के लिए आप करते हैं, जैसा कि घटनाएं होती हैं कई बार निकाल दिया। तो पांच बार आवेदन करने के बाद, एक क्लिक: बाइंडिंग को पांच बार निकाल दिया जाएगा, इसलिए यह एक वांछनीय समाधान नहीं है;)

क्या कुछ भी है जैसे ko.update बाइंडिंग्स() या कुछ और, नॉकआउट को बताने के लिए .. तत्व बाइंडिंग अद्यतन करें?

अभिवादन, क्रिस

+1

क्या आप कुछ कोड पोस्ट कर सकते हैं यह दिखाने के लिए कि आप क्या कर रहे हैं? –

+0

अच्छी तरह से, उदाहरण के लिए कुछ: $ ('body')। संलग्न करें ('Click me!'); –

+0

मुझे यकीन नहीं है कि सहायक उत्तर प्रदान करने के लिए पर्याप्त संदर्भ है। मैं समझता हूं कि आप क्या करने की कोशिश कर रहे हैं, लेकिन आपके कोड की एक पूर्ण तस्वीर (क्यों/जब आप नए डोम तत्वों को इंजेक्ट कर रहे हैं) के साथ इसका ख्याल रखने का सबसे अच्छा तरीका जवाब देना मुश्किल है। यह आपके वर्तमान समाधान को देखने के बाद हो सकता है कि कोई भी नए तत्वों को इंजेक्ट करने के लिए एक तरीका बता सकता है या आप जो करने की कोशिश कर रहे हैं उसके लिए एक कामकाज है। –

उत्तर

35

हर बार जब आप आह्वान ko.applyBindings पूरे DOM बाइंडिंग के लिए निरीक्षण किया जाता है। नतीजतन आप प्रत्येक तत्व के लिए कई बाइंडिंग प्राप्त करेंगे यदि आप इसे एक से अधिक बार करते हैं।

ko.applyBindings(viewModelA, document.getElementById("newElement")); 

इस संबंधित सवाल देखें::

Can you call ko.applyBindings to bind a partial view?

+1

हां, यह समाधान भी है जिसके साथ मैं आया था :) दुख की बात है कि मुझे knockoutjs.com पर एक प्रत्यक्ष एपीआई दस्तावेज मिला है और इसे खोजने के लिए को ऑब्जेक्ट पर कुछ रिवर्स इंजीनियरिंग करना था- - –

+1

सच है, कोई नहीं है एपीआई दस्तावेज, लेकिन यह अधिक 'wordy' दस्तावेज में है। इस पृष्ठ के नीचे आधा रास्ता देखें: http://knockoutjs.com/documentation/observables.html – ColinE

+0

क्या आप वाकई जवाब दे रहे हैं? क्या यह newMleelA को newElement पर लागू नहीं करेगा, जैसे कि न्यूएलमेंट डीओएम की रूट है जो मॉडेल के लिए है? मैं देख सकता हूं कि यह कहां से काम करेगा या यहां तक ​​कि अधिकतर बार, लेकिन मैं यह भी देख सकता हूं कि यह उत्पाद अप्रत्याशित परिणाम कैसे हो सकता है (मुझे लगता है)। –

7

जानते हुए भी कि तुम क्या कर रहे हैं के बिना आप बस एक नई डोम तत्व बाध्य करने के लिए चाहते हैं तो आप applyBindings समारोह के लिए एक पैरामीटर के रूप में इस तत्व पारित कर सकते हैं बिल्कुल ठीक है, ऐसा लगता है कि आप इसके बारे में गलत तरीके से जा रहे हैं। आपका विचार आपके दृश्य मॉडल द्वारा संचालित किया जाना चाहिए। तो आपको सीधे डोम तत्वों को नहीं जोड़ना चाहिए, इसके बाद आपको नॉकआउट बाइंडिंग लागू करने की आवश्यकता है।

इसके बजाय आपको दृश्य में परिवर्तन को दर्शाने के लिए अपना दृश्य मॉडल अपडेट करना चाहिए, जिसके बाद आपका नया तत्व प्रकट हो सकता है।

तो उदाहरण के लिए, आपके $('body').append('<a href="#" data-bind="click: something">Click me!</a>'); के लिए, बटन को दिखाई देने पर DOM तत्व जोड़ने के बजाय, दृश्य मॉडल का उपयोग करके बटन दृश्यता को नियंत्रित करें।

तो आपके विचार मॉडल

var viewModel = { clickMeAvailable: ko.observable(false) } 

भी शामिल है और अपने HTML

<a href="#" data-bind="click: something, visible: clickMeAvailable">Click me!</a> 

जब ऐसा आवेदन स्थिति परिवर्तन मुझे बटन पर क्लिक करें उपलब्ध है तो बस viewModel.clickMeAvailable(true) भी शामिल है, तुम।

ऐसा करने का बिंदु, और नॉकआउट का एक बड़ा हिस्सा प्रस्तुति से व्यावसायिक तर्क को अलग करना है। तो कोड जो मुझे उपलब्ध कराता है, परवाह नहीं करता है कि मुझे क्लिक करें एक बटन शामिल है। जब मैं क्लिक करता हूं तो यह सब viewModel.clickMeAvailable अपडेट होता है।

उदाहरण के लिए, मुझे क्लिक करें एक सहेजें बटन है जो एक फॉर्म वैध रूप से भरने पर उपलब्ध होना चाहिए। आप formValid मॉडल को देखने योग्य देखने के लिए सहेजें बटन दृश्यता को जोड़ देंगे।

लेकिन फिर आप फॉर्म को वैध होने के बाद चीजों को बदलने का फैसला करते हैं, एक कानूनी समझौता दिखाई देता है जिसे सहेजने से पहले सहमति दी जानी चाहिए। आपके फॉर्म का तर्क बदलता नहीं है - यह फॉर्म वैध होने पर भी formValid सेट करता है। formValid परिवर्तनों में परिवर्तन होने पर आप बस बदलेंगे।

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

+0

जबकि मैं निश्चित रूप से यह सब से सहमत हैं, मुझे लगता है कि कई बार जब यह भावना एक तरह से knockoutjs है कि आप के साथ अंत लाभ उठाने के लिए पड़ता है देखते हैं" नेस्टेड "दृश्य मॉडल। इस स्थिति की तर्ज पर अधिक हो सकता है कि ईसाई साथ। रिकॉर्ड के लिए काम कर रहा था जो मामले में आप एक दृश्य के मॉडल है कि है विशेष रूप से के लिए स्थापित करने और अपने नेस्ट (संभवतः ajax के माध्यम से में खींच लिया) एचटीएमएल करने के लिए बाध्य है, जब यह उपलब्ध है/लोड हो जाए, होना चाहिए। – Jed

+0

, मुझे लगता है कि यह है सही जवाब। नियंत्रण घोषणा, घटना व्यवहार से प्रेरित नहीं पर बाध्य किया जाना चाहिए। नॉकआउट उन प्रौद्योगिकियों जहां पूरे दृष्टिकोण बनाए रखने के लिए कम से कम कष्टप्रद कीड़े से बचने की जरूरत से एक है। –

+3

क्या जहां दृश्य विशेष रूप से बड़ी साइटों के बारे में खुद बदल रहा है? क्या सभी संभावित विचार डिफ़ॉल्ट पृष्ठ में पैक किए जाने चाहिए? निश्चित रूप से नहीं। साइट के अन्य "क्षेत्रों" में संक्रमण के रूप में AJAX के माध्यम से एक दृश्य लोड करना निश्चित रूप से एक है स्वीकार्य कार्रवाई (मैं व्यक्तिगत रूप से इसे एक वेब एप्लिकेशन में उपयोग कर रहा हूं जिसे मैं परिवर्तित कर रहा हूं। मूल आवेदन एमवीसी 4 है और मेरे पास ट्रैकिंग के विभिन्न व्यक्तिगत प्रबंधन डेटा (स्टॉक, अन्य वित्तीय, टोडो सूची, संपर्क सूची, ईवेंट कैलेंडर) के लिए अलग-अलग विचार हैं। चूंकि वे सभी एक ही मास्टर पेज का उपयोग करते हैं, इसलिए उन्हें एमवीवीएम/नॉकआउट में परिवर्तित करना काफी सीधे है। – lassombra

0

मुझे पता है कि आपने बहुत समय पहले पूछा था, लेकिन मैं बस इसी तरह की समस्या पर ठोकर खाई। मैंने कंटेनर में नए तत्व जोड़ने की कोशिश की और उनको एक ऑनक्लिक फ़ंक्शन दिया। पहली बार आपने जो चीजें की थीं, और यहां तक ​​कि ColinErecommended दृष्टिकोण की कोशिश की। यह मेरे लिए एक व्यावहारिक समाधान नहीं था, इसलिए मैं SamStephens दृष्टिकोण की कोशिश की और कहा कि के साथ आया था, जो मेरे लिए पूरी तरह से workes:

HTML:

<div id="workspace" data-bind="foreach:nodeArr, click:addNode"> 
<div class="node" data-bind="attr:{id:nodeID},style:{left:nodeX,top:nodeY},text:nodeID, click:$parent.changeColor"></div> 
</div> 

जावास्क्रिप्ट:

<script> 
function ViewModel() { 
var self = this; 
var id = 0; 
self.nodeArr = ko.observableArray(); 
self.addNode = function (data, event) { 
    self.nodeArr.push({ 
     'nodeID': 'node' + id, 
     'nodeX' : (event.offsetX - 25) + 'px', 
     'nodeY' : (event.offsetY - 10) + 'px' 
    }) 
    id++; 
} 
self.changeColor = function(data, event){ 
    event.stopPropagation(); 
    event.target.style.color = 'green'; 
    event.target.style.backgroundColor = 'white'; 
} 
} 
ko.applyBindings(new ViewModel()); 
</script> 

आप कर सकते हैं मैंने बनाया JS Fiddle में इसके साथ खेलो। आशा है कि यह अभी भी किसी की मदद करेगा।

+1

ठीक है, मेरे लिए ... मैंने बहुत समय पहले नॉकआउटजेएस को त्याग दिया क्योंकि यह मेरे उद्देश्यों के लिए बहुत ही लचीला था। –

+0

@ChristianEngel को शायद ही अनम्य .. कुछ बातें जो का उपयोग करता है को जिस तरह से (मैं अभी तक rebind करने की आवश्यकता को खोजने के लिए है!) सुखद हो के लिए किया जाना करने की जरूरत है, लेकिन [Durandal] (http://durandaljs.com) (है केओ) -> विचारों के समर्थन के साथ भयानक लचीलापन - अलग-अलग विचार मैन्युअल रूप से आंशिक रूप से बाध्य करने की आवश्यकता को कम करने की आवश्यकता को कम करते हैं क्योंकि प्रत्येक दृश्य या तो इसे अपना मॉडल पेश कर सकता है या मॉडल का हिस्सा साझा कर सकता है। अब, केओ के बारे में कुछ चीजें हैं जो मुझे पसंद नहीं हैं, लेकिन लचीलापन की कमी के साथ इसका कोई लेना-देना नहीं है! एक बार जब इसका उपयोग पूरी तरह से किया जाता है तो अवलोकन योग्य मॉडल * बहुत * लचीला होता है। – user2246674

+0

@ChristianEngel यादृच्छिक (बाह्य) तत्वों को संभालने के लिए "hackish लेकिन आसान" जिस तरह से डोम में इंजेक्ट किया जा रहा है 'if' तरह बंधन (इस पोस्ट' foreach' जो यकीनन क्लीनर शुरू करने के लिए है पता चलता एक * प्रवाह नियंत्रण में उन्हें डालने के लिए * है साथ) और उसके बाद तत्वों को डालने के बाद "चालू" सामग्री टॉगल करें - नया उपट्री बस उचित के रूप में बाध्य होगा। * कोई * अतिरिक्त मैनुअल 'लागू बाइंडिंग' और प्रवाह-बाध्यकारी पर एक अवलोकन योग्य नियंत्रण है। दायरे में गुणों को परिष्कृत करने के लिए 'withProperties' जैसी अतिरिक्त बाइंडिंग का उपयोग किया जा सकता है। – user2246674

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