2013-03-20 10 views
5

मैं नॉकआउट के साथ कुछ जटिल बाध्यकारी करने की कोशिश कर रहा हूं (कम से कम मेरे जैसे नौसिखिया के लिए)।knockout.js रिकर्सिव बाइंडिंग

निम्न डेटा पर विचार करें:

var originalData = { 
id: 1, 
name: "Main", 
children: [ { id: 2, name: "bob", children: []}, { id: 3, name: "ted", children: [{id: 5, name:"albert"}, {id: 9, name: "fred"}]} ], 
selectedChild: { id: 2, name: "bob" } 
}; 

<table> 
<tr> 
    <td data-bind="text: name"></td> 
</tr> 
<tr data-bind="if: children().length > 0"> 
    <td> 
     <select data-bind="options: children, 
      optionsText: function(item){ 
       return item.name; 
        }, 
      optionsCaption: 'Choose...'"></select>  
    </td> 
</tr> 

ठीक है, कि आसान हिस्सा था।

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

मुझे इस समस्या को नॉकआउट के साथ कैसे हल करना चाहिए? http://jsfiddle.net/graphicsxp/qXZjM/

+0

एक विचार है कि मेरे दिमाग में आता है, अंदर ही सलेक्ट बॉक्स के साथ एक टेम्पलेट का उपयोग करें और जब बच्चों के साथ एक आइटम का चयन किया गया है तालिका तत्व है कि टेम्पलेट संलग्न करने के लिए है। यह अभी तक स्पष्ट नहीं है कि मैं इसे कैसे करने जा रहा हूं लेकिन क्या आपको लगता है कि मैं सही रास्ते पर हूं? – Sam

उत्तर

9

आप एक script टैग में टेम्पलेट रख कर नॉकआउट में पुनरावर्ती टेम्पलेट का उपयोग कर सकते हैं:

मैं एक साथ मैं क्या jsfiddle पर अब तक राशि का एक नमूना डाल दिया है। एक script टैग में टेम्पलेट्स खुद को संदर्भित कर सकते हैं, इस तरह:

<div data-bind="template: 'personTemplate'"></div> 

<script type="text/ko" id="personTemplate"> 
    <span data-bind="text: name"></span> 
    <select data-bind="options: children, optionsText: 'name', optionsCaption: 'Choose', value: selectedChild"></select> 
    <!-- ko if: selectedChild --> 
    <div data-bind="template: { name: 'personTemplate', data: selectedChild }"></div> 
    <!-- /ko --> 
</script> 

यहाँ है the fiddle


अद्यतन:

आप एक computed का उपयोग आसानी से कर सकते हैं, और हटाने दृश्य से तर्क (जो मुझे लगता है कि इस मामले में बेहतर है), और उसके बाद if को बांधें।

self.showChildren = ko.computed(function() { 
    return self.selectedChild() 
     && self.selectedChild().children().length > 0; 
}); 

आप if ब्लॉक में दोनों रखना चाहते हैं, तो आप, तो आप सिर्फ कोष्ठक शामिल करने की जरूरत कर सकते हैं। इसका कारण यह है कि अवलोकन कार्य कार्य करते हैं; नॉकआउट आपको उनको बहिष्कृत करने देता है यदि आप केवल एक संदर्भ का उपयोग कर रहे हैं, लेकिन उन्हें अपनी संपत्तियों को "ड्रिल डाउन" करने की आवश्यकता है।

if: selectedChild() && selectedChild().children().length > 0 

यहाँ updated fiddle

+0

आपको बहुत बहुत धन्यवाद, यह शानदार लग रहा है! मुझे बहुत कुछ चाहिए जो मुझे चाहिए। हालांकि, एक बात यह है कि, मैं इसे मैपिंग प्लगइन का उपयोग करके काम नहीं कर सकता, जबकि आपने हार्ड-कोड किए गए व्यक्ति फ़ंक्शन का उपयोग किया है। क्या आप मुझे बता सकते हैं कि मैं क्या गलत कर रहा हूं? jsfiddle यहां: http://jsfiddle.net/graphicsxp/qXZjM/ – Sam

+0

वास्तव में मेरी टिप्पणी को अनदेखा करता है, यह अब काम करता है। मुझे सिर्फ चयनित चाइल्ड गुणों को ko.observable() पर सेट करने की आवश्यकता है। आपका बहुत बहुत धन्यवाद ! – Sam

+0

एक आखिरी सवाल: यदि आप बाध्यकारी को संशोधित करते हैं तो टेम्पलेट केवल तभी दिखाता है जब चयनित चाइल्ड के लिए कम से कम एक बच्चा है? मैंने कोशिश की है अगर: चयनित चाइल्ड && चयनितChild.children.length> 0 लेकिन यह काम नहीं करता .... कोई विचार? – Sam

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