web-dev-qa-db-fra.com

Guidon/Moustache - Existe-t-il une méthode intégrée pour parcourir les propriétés d'un objet?

Comme le titre de la question le dit, existe-t-il un moyen de faire une boucle moustache/guidon à travers un object properties?

Donc avec 

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

Puis-je alors faire quelque chose dans le moteur de gabarit} qui serait équivalent à

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

?

194
Ben

Prise en charge intégrée depuis le guidon 1.0rc1

La prise en charge de cette fonctionnalité a été ajoutée à Handlebars.js. Il n’ya donc plus besoin d’aide externe.

Comment l'utiliser

Pour les tableaux:

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

Pour les objets:

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

Notez que seules les propriétés ayant passé le test hasOwnProperty seront énumérées.

401
Jon

C'est en fait assez facile à implémenter en tant qu'assistant:

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

Puis l'utiliser comme ça:

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

EDIT: Le guidon a maintenant un moyen intégré d’y parvenir; voir le réponse sélectionnée ci-dessus . Lorsque vous travaillez avec Plain Moustache, les indications ci-dessous s'appliquent toujours.

Moustache peut parcourir les éléments d'un tableau. Je suggérerais donc de créer un objet de données séparé formaté de façon à ce que Moustache puisse fonctionner avec:

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]
     });
  }
}

Maintenant, votre modèle de moustache serait quelque chose comme:

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

Consultez la section "Listes non vides" ici: https://github.com/janl/mustache.js

27
Amit

Ceci est la réponse de @ Ben mise à jour pour être utilisée avec Ember ... remarque, vous devez utiliser Ember.get car le contexte est transmis sous forme de chaîne. 

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;
});

Modèle:

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

La réponse de @ Amit est bonne car elle fonctionnera à la fois avec Moustache et avec le Guidon.

En ce qui concerne les solutions réservées au guidon, j’en ai vu quelques-unes et j’aime bien l’assistant de bloc each_with_key à https://Gist.github.com/1371586 the best.

  • Il vous permet d’itérer sur des littéraux d’objet sans avoir à les restructurer d’abord, et 
  • Cela vous donne le contrôle sur ce que vous appelez la variable clé. Avec de nombreuses autres solutions, vous devez faire attention à l’utilisation de clés d’objet nommées 'key', ou 'property', etc.
1
mjumbewu

Merci pour la solution de Ben, mon cas d'utilisation pour afficher uniquement des champs particuliers dans l'ordre

avec objet

Code:

    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;
});

Objet source:

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

Modèle:

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

Sortie:

locationDesc --- abc
description --- def
name --- ghi
0
vincentlcy

C'est une fonction d'assistance pour moustacheJS, sans pré-formater les données mais les récupérer pendant le rendu.

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'
        }
    }
};

Modèle:

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

Les sorties:

color: blue
color: red

(l'ordre peut être aléatoire - c'est une carte) .__ Ceci peut être utile si vous connaissez l'élément de carte que vous voulez. Faites juste attention aux valeurs de fausseté.

0
Cuel

J'utilisais l'ancienne version 1.0.beta.6 du guidon, je pense que quelque part au cours de la 1.1 - 1.3 cette fonctionnalité a été ajoutée.

Usage:

{{#each object}}
  Key {{@key}} : Value {{this}}
{{/people}}
0
AamirR