Ручки / вуса - чи існує вбудований спосіб прокручування властивостей об'єкта?


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

Вбудована підтримка з рукоятки 1.0rc1

Підтримка цієї функціональності додана до Handlebars.js, тому більше немає потреби у зовнішніх помічниках.

Як ним користуватися

Для масивів:

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

Для об'єктів:

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

Зауважте, що hasOwnPropertyбудуть перераховані лише властивості, які проходять тест.


2
@Rafi: цього не можна багато розуміти, не знаючи вашої структури даних.
Джон

3
@Rafi: ти не маєш на увазі {{this.title}}?
невин

2
@qodeninja: Просто: так само, як ви ставитесь до значень у прикладах, наведених вище - з {{#each this}}. Ваш вибір термінів також заплутаний (що робить один об'єкт "найвищим рівнем", а інший - ні, що таке "заздалегідь визначені" клавіші? Тощо), тож ви можете переглянути ці поняття.
Jon

1
якщо не помиляюся, то тільки з v1.1.0 це доступно, але чудова відповідь дякую.
Renars Sirotins

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 всередині циклу, щоб ви не повторювали властивості прототипу?
monkeyboy

Чудове рішення @Ben. У випадку, якщо хтось намагається використати це з Ембер, дивіться мою відповідь нижче, щоб вирішити проблему.
мухомор

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
Закінчилося з вашою пропозицією, оскільки мені потрібно пройти деякі додаткові властивості. Дякую за допомогу!
Бен

Велике спасибі, ваша ідея врятувала мене ще один день пошуку альтернатив. Цей рядок є ключовим вусомFormattedData = {'люди': []};
Метт

Як би ви це зробили з масивом "o" об'єктів?
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'тощо.

Приємна знахідка. Просто попередження для інших читачів: помічник "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

Це допоміжна функція для mustacheJS, без попереднього форматування даних та замість отримання їх під час візуалізації.

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 та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.