हैंडलबार्स / मूंछें - क्या किसी वस्तु के गुणों के माध्यम से लूप बनाने का तरीका है?


216

जैसा कि सवाल का शीर्षक कहता है, क्या किसी ऑब्जेक्ट गुणों के माध्यम से लूपिंग की मूंछें / हैंडलबार तरीका है ?

के साथ

var o = {
  bob : 'For sure',
  roger: 'Unknown',
  donkey: 'What an ass'
}

क्या मैं तब टेम्पलेट इंजन में कुछ कर सकता हूं जो इसके समकक्ष होगा

for(var prop in o)
{
    // with say, prop a variable in the template and value the property value
}

?

जवाबों:


448

अंतर्निहित समर्थन के बाद से Handlebars 1.0rc1

इस कार्यक्षमता के लिए समर्थन को हैंडलबार्स.जेएस में जोड़ा गया है , इसलिए बाहरी सहायकों की अधिक आवश्यकता नहीं है।

इसे कैसे उपयोग करे

सरणियों के लिए:

{{#each myArray}}
    Index: {{@index}} Value = {{this}}
{{/each}}

वस्तुओं के लिए:

{{#each myObject}}
    Key: {{@key}} Value = {{this}}
{{/each}}

ध्यान दें कि केवल hasOwnPropertyपरीक्षा में पास होने वाले गुणों की गणना की जाएगी।


2
@ रफी: हालांकि आपकी डेटा संरचना को जाने बिना इसका बहुत अर्थ नहीं निकाला जा सकता है।
जॉन

3
@Rafi: क्या आपका मतलब {{this.title}} नहीं है?
नव्विन

2
@qodeninja: सरल: उसी तरह जिस तरह से आप ऊपर के उदाहरणों में मूल्यों का उल्लेख करते हैं - साथ {{#each this}}। आपकी पसंद की शर्तें भी भ्रामक हैं (क्या एक वस्तु को "शीर्ष स्तर" बनाती है और दूसरे को नहीं? "पूर्व-परिभाषित" कुंजियां वास्तव में क्या हैं? आदि), इसलिए आप इन अवधारणाओं को फिर से देखना चाहते हैं।
जॉन

1
यदि गलत नहीं है, तो केवल v1.1.0 के साथ यह उपलब्ध है, लेकिन महान जवाब धन्यवाद।
रेनारोस सिरोटिन्स

2
आप केवल संपत्तियों के एक विशिष्ट श्वेतसूची के लिए ऐसा कैसे करते हैं?
मार्को प्रिन्स

70

सहायक के रूप में लागू करना वास्तव में काफी आसान है:

Handlebars.registerHelper('eachProperty', function(context, options) {
    var ret = "";
    for(var prop in context)
    {
        ret = ret + options.fn({property:prop,value:context[prop]});
    }
    return ret;
});

फिर इसे इस तरह से उपयोग करना:

{{#eachProperty object}}
    {{property}}: {{value}}<br/>
{{/eachProperty }}

2
अच्छा लग रहा है, क्या आपको लूप के अंदर hasOwnProperty चेक जोड़ने की आवश्यकता है ताकि आप प्रोटोटाइप गुणों पर ध्यान न दें?
मंकीबॉय

महान समाधान @ बान। यदि कोई भी एम्बर के साथ इसका उपयोग करने की कोशिश कर रहा है, तो समाधान पाने के लिए नीचे दिए गए मेरे जवाब को देखें।
फ्लाईनफिश

27

EDIT: हैंडलबार्स के पास अब इसे पूरा करने का एक अंतर्निहित तरीका है; ऊपर दिए गए उत्तर को देखें । सादे मूंछों के साथ काम करते समय, नीचे अभी भी लागू होता है।

मूंछें एक सरणी में वस्तुओं पर पुनरावृति कर सकती हैं। इसलिए मैं सुझाव दूंगा कि मूंछें जिस तरह से काम कर सकती हैं, उसमें एक अलग डेटा ऑब्जेक्ट तैयार किया जाए:

var o = {
  bob : 'For sure',
  roger: 'Unknown',
  donkey: 'What an ass'
},
mustacheFormattedData = { 'people' : [] };

for (var prop in o){
  if (o.hasOwnProperty(prop)){
    mustacheFormattedData['people'].push({
      'key' : prop,
      'value' : o[prop]
     });
  }
}

अब, आपकी मूंछें टेम्प्लेट कुछ इस तरह होंगी:

{{#people}}
  {{key}} : {{value}}
{{/people}}

यहां "गैर-खाली सूची" अनुभाग देखें : https://github.com/janl/mustache.js


1
जैसे ही मुझे कुछ अतिरिक्त उप गुणों को पारित करने की आवश्यकता होती है, आपके सुझाव के साथ समाप्त हो गया। सहायता के लिए धन्यवाद!
बेन

बहुत बहुत धन्यवाद, आपके विचार ने मुझे विकल्प की तलाश में एक और दिन बचा लिया। यह पंक्ति प्रमुख मूंछें हैफोरमैटडैट = {'लोग': []};
मैट

आप "ओ" ऑब्जेक्ट की एक सरणी के साथ यह कैसे करेंगे?
red888

4

यह @ एम्बर के साथ उपयोग के लिए अपडेट किया गया बेन का उत्तर है ... ध्यान दें कि आपको उपयोग करना होगा Ember.getक्योंकि संदर्भ को स्ट्रिंग के रूप में पारित किया गया है।

Ember.Handlebars.registerHelper('eachProperty', function(context, options) {
  var ret = "";
  var newContext = Ember.get(this, context);
  for(var prop in newContext)
  {
    if (newContext.hasOwnProperty(prop)) {
      ret = ret + options.fn({property:prop,value:newContext[prop]});
    }
  }
  return ret;
});

टेम्पलेट:

{{#eachProperty object}}
  {{key}}: {{value}}<br/>
{{/eachProperty }}

धन्यवाद @flynfish संदर्भ एम्बर में एक स्ट्रिंग है ?? ऐसा लगता है .. कुछ अजीब है।
बेन

हाँ, मैं वास्तव में यकीन नहीं कर रहा हूँ क्योंकि मैं एम्बर के लिए नया हूँ और अभी भी इसके चारों ओर अपना रास्ता खोजने की कोशिश कर रहा हूँ।
फ्लाईनफिश

1

@ अमित का जवाब अच्छा है क्योंकि यह मूंछ और हैंडल दोनों में काम करेगा।

जहाँ तक हैंडल-ओनली सॉल्यूशंस की बात है, मैंने कुछ देखा है और मुझे each_with_keyब्लॉक हेल्पर https://gist.github.com/1371586 सबसे अच्छा लगा।

  • यह आपको पहले उन्हें पुन: व्यवस्थित करने के लिए वस्तु शाब्दिकों पर पुनरावृति करने की अनुमति देता है, और
  • यह आपको कुंजी चर को कॉल करने पर नियंत्रण देता है। कई अन्य समाधानों के साथ, आपको नामित वस्तु 'key', या 'property', आदि का उपयोग करने के बारे में सावधान रहना होगा ।

अच्छा लगा। अन्य पाठकों के लिए बस एक चेतावनी: इस gist में "key_value" सहायक में एक बग है। इसे ठीक करने के लिए टिप्पणियों को पढ़ें।
सायरनटियन

0

बेन के समाधान के लिए धन्यवाद, क्रम में केवल विशेष फ़ील्ड प्रदर्शित करने के लिए मेरा उपयोग मामला

वस्तु के साथ

कोड:

    handlebars.registerHelper('eachToDisplayProperty', function(context, toDisplays, options) {
    var ret = "";
    var toDisplayKeyList = toDisplays.split(",");
    for(var i = 0; i < toDisplayKeyList.length; i++) {
        toDisplayKey = toDisplayKeyList[i];
        if(context[toDisplayKey]) {
            ret = ret + options.fn({
                property : toDisplayKey,
                value : context[toDisplayKey]
            });
        }

    }
    return ret;
});

स्रोत वस्तु:

   { locationDesc:"abc", name:"ghi", description:"def", four:"you wont see this"}

टेम्पलेट:

{{#eachToDisplayProperty this "locationDesc,description,name"}}
    <div>
        {{property}} --- {{value}}
    </div>
    {{/eachToDisplayProperty}}

आउटपुट:

locationDesc --- abc
description --- def
name --- ghi

0

यह डेटा को पूर्व-स्वरूपित किए बिना और उसे रेंडर करने के दौरान प्राप्त करने के बिना मूंछें के लिए एक सहायक कार्य है।

var data = {
    valueFromMap: function() {
        return function(text, render) {
            // "this" will be an object with map key property
            // text will be color that we have between the mustache-tags
            // in the template
            // render is the function that mustache gives us

            // still need to loop since we have no idea what the key is
            // but there will only be one
            for ( var key in this) {
                if (this.hasOwnProperty(key)) {
                    return render(this[key][text]);
                }
            }
        };
    },

    list: {
        blueHorse: {
            color: 'blue'
        },

        redHorse: {
            color: 'red'
        }
    }
};

टेम्पलेट:

{{#list}}
    {{#.}}<span>color: {{#valueFromMap}}color{{/valueFromMap}}</span> <br/>{{/.}}
{{/list}}

आउटपुट:

color: blue
color: red

(आदेश यादृच्छिक हो सकता है - यह एक नक्शा है) यह उपयोगी हो सकता है यदि आप उस मानचित्र तत्व को जानते हैं जो आप चाहते हैं। बस मिथ्या मूल्यों के लिए बाहर देखो।


-1

मैं 1.0.beta.6हैंडलबार्स के पुराने संस्करण का उपयोग कर रहा था , मुझे लगता है कि 1.1 के दौरान कहीं - 1.3 इस कार्यक्षमता को जोड़ा गया था, इसलिए 1.3.0 को अपडेट करने से समस्या हल हो गई, यहां उपयोग है:

उपयोग:

{{#each object}}
  Key {{@key}} : Value {{this}}
{{/people}}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.