2012-02-07 13 views
38

मैं निम्नलिखित टेम्पलेट का उपयोग कर रहा हूँ:Knockout.js - foreach बंधन - परीक्षण करता है, तो पिछले तत्व

<div class="datatypeOptions" data-bind="if: $data.datatypeTemplate().allowOptions"> 
    <h3>Allowed responses</h3> 

    <p data-bind="if: $data.datatypeTemplate().datatypeOptions().length == 0">There are no responses for this question, yet. <a href="#" data-bind="click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());}">Add one</a> 
    <ul data-bind="foreach: $data.datatypeTemplate().datatypeOptions()"> 
     <li> 
      <a href="#" data-bind="text: name, click: $root.selectedDatatypeOption, visible: $data !== $root.selectedDatatypeOption()"></a> 
      <input data-bind="value: name, visibleAndSelect: $data === $root.selectedDatatypeOption(), event: { blur: $root.clearDatatypeOption }, executeOnEnter: { callback: function(){ $root.addDatatypeOption($parent.datatypeTemplate()); } }" /> 
      //I want to show this a tag only if $data is the last element in the array. 
Problem here ===> <a href="#" data-bind="if: $data == $parent.datatypeTemplate().datatypeOptions()[ $parent.datatypeTemplate().datatypeOptions().length - 1 ], click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());}"><img src='/static/img/icons/custom-task-wizard/black/plus_12x12.png' title='Add option'></a> 
     </li> 
    </ul> 
</div> 

मैं कंसोल में इस त्रुटि मिलती है:

Uncaught Error: Unable to parse bindings. 
Message: TypeError: Object [object Object] has no method 'datatypeTemplate'; 
Bindings value: if: $data == $parent.datatypeTemplate().datatypeOptions()[ $parent.datatypeTemplate().datatypeOptions().length - 1 ], click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());} 

मेरी केवल एक जोड़ने का विकल्प है मेरे व्यूमोडेल पर फ़ंक्शन जो सत्य/गलत लौटाता है यदि पास तत्व तत्व सरणी में रहता है?

+0

http://memegenerator.net/instance/14211604 का समाधान नहीं – Jonathan

+2

आप jsFiddle में यह पुन: पेश करने की कोशिश करना चाहते हो सकता है हल करती है। एक बात मैंने नोटिस की है कि आप अपने 'पी' टैग को बंद कर रहे हैं, जो बाध्यकारी/संदर्भ में समस्याएं पैदा कर सकता है। अंतिम आइटम निर्धारित करने में सहायता के लिए आप अपने व्यू मॉडल पर गणना किए गए अवलोकन योग्य या फ़ंक्शन डालकर अपना व्यू क्लीनर रख सकते हैं। –

उत्तर

0

निम्नलिखित का प्रयास करें:

  1. उपयोग $root बजाय $parent
  2. अग्रिम में अंतिम आइटम तैयार करें और अतिरिक्त पैरामीटर के रूप में अपने टेम्पलेट के लिए यह आइटम गुजरती हैं।
  3. देखने योग्य करने के लिए अंतिम तत्व को समाहित करें।
73

मैंने समस्या को सरल बना दिया है, लेकिन यह jsFiddle एक संभावित समाधान प्रदर्शित करता है।

"अगर" बंधन:

<div data-bind="if: ($index() === ($parent.data().length - 1))">I'm the last element</div> 

Containerless "अगर" बंधन:

<!-- ko if: ($index() === ($parent.data().length - 1)) --> 
<div>I'm the last element again</div> 
<!-- /ko --> 

आप वर्तमान के सूचकांक पाने के लिए बाध्यकारी एक foreach भीतर $index उपयोग कर सकते हैं बाध्य वस्तु माता-पिता के मूल संग्रह के मुकाबले तुलना करने के लिए इसका इस्तेमाल करें।

बाध्यकारी संदर्भों के बारे में अधिक जानकारी के लिए HERE देखें।

+1

दुर्भाग्यवश, यदि आप 'as' विकल्प का उपयोग करते हैं, तो' $ डेटा' भी बाध्य नहीं है .. बस एक "गॉचा"। – user2246674

+0

यह मेरे लिए काम नहीं करता है, मुझे लगता है कि शायद बी/सी मैं नॉकआउट वी 2.2.1 पर हूं। हालांकि निम्नलिखित ने काम किया (माईविंगडिंग्स को अपने सरणी ऑब्जेक्ट के नाम से निश्चित रूप से बदलें)। डेटा-बाइंड = "दृश्यमान: $ अनुक्रमणिका() <$ parent.MyWingDings.length - 1" – Sean

+0

@ user2246674 ** देखें [मेरा उत्तर] (http://stackoverflow.com/a/076/4390133) ** मामले में आप 'as' विकल्प का उपयोग कर रहे हैं –

8

मैंने देखा KO संवर्द्धन के लिए अनुरोध के एक नंबर कारणों (अक्सर प्रदर्शन) की एक किस्म के लिए, हालांकि foreach बंधन में $length, $last, या $array सुरक्षित गुण समर्थन करने के लिए देखते हैं, वे इसे में नहीं किया है codebase।

यदि कोई कस्टम बाध्यकारी का उपयोग करके किसी विशिष्ट मामले के लिए इन तत्वों को उजागर करने में रुचि रखता है, तो "सुंदर" सूची मुद्रित करने के लिए $length चर को उजागर करने का एक सरल उदाहरण यहां दिया गया है।
आप forEachWithLength का उपयोग कहीं भी करते हैं, जहां आप आम तौर पर foreach का उपयोग करेंगे।

ko.bindingHandlers.forEachWithLength = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) 
    {   
     return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, context); 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, context) 
    {   
     var array = ko.utils.unwrapObservable(valueAccessor()); 
     var extendedContext = context.extend({"$length" : array.length }); 
     ko.bindingHandlers.foreach.update(element, valueAccessor, allBindingsAccessor, viewModel, extendedContext); 
    } 
}; 

उदाहरण उपयोग:

<div data-bind="forEachWithLength: myArray"> 
    <span data-bind="text: $data"></span> 
    <!-- ko if: ($index() < $length-2) -->, <!-- /ko --> 
    <!-- ko if: ($index() === $length-2) --> and <!-- /ko --> 
</div> 

इनपुट:["One", "Two", "Three", "Four"]

आउटपुट:One, Two, Three and Four

Fiddle

Further reading

2

यदि आप हैं नहींforeach में as विकल्प बंधन का उपयोग कर, तो most-upvoted answer to this question में जाते हैं।

यदि आप DOas ऑपरेटर foreach बाध्यकारी में उपयोग कर रहे हैं। तो वह जवाब नहीं काम करेगा।

यहाँ उस मामले में समाधान है

<div data-bind="foreach:{data: Items, as :'item'}"> 
    <div data-bind="if: ($index() === ($parent.Items().length - 1))">I'm the last element</div> 
</div> 

नमूदार सरणी आप मेरे मामले में उपयोग कर रहे हैं यह Items नामित किया गया था के नाम के साथ $parent.data() की जगह है, इसलिए मैं $parent.data() के साथ बदल के साथ गुप्त $parent.Items()

नोटइस समाधान सभी मामलों में काम कर रहा है, इस स्थिति में आप as विकल्प है या नहीं का उपयोग कर रहे टी,
लेकिन पहले मामले में यह कुछ है कि सबसे upvoted जवाब

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