2013-10-12 7 views
9

У меня есть Ember.Object, который используется как базовый словарь ключей/значений. Имена ключей являются динамическими, и то, что я хотел бы сделать, это перебрать эти свойства. Похоже, это должно быть легко, но поисковые запросы Google и мой коллективный анализ царапин не указывают на очевидный ответ, который я ожидал.Итерация через объект Ember

Для следующего кода псевдо:

App.MyObject = Ember.Object.extend({ 
    randomComputedProperty: function() { 
     return "foobar"; 
    }  
} 
$object = new MyObject.create(someBigAndUnpredictableNameValueHash); 

Мой идеальным решением было бы решить для этого кода позволит мне быстро различить:

  • Критически: массив имен свойств, что object имеет
  • В идеале: массив вычисленных имен свойств, который object имеет
  • Icing-on-the-Top: массив вычислений ed, которые включают сеттеры вдоль геттера

В любом случае есть идеи?

----- UPDATE -----

Чтобы быть немного более четко о моем точном использовании. Вымышленный MyObject на самом деле это свойство, которое приходит от одного моих моделей:

App.MyModel = DS.Model.extend({ 
    prop1: DS.attr('string'), 
    prop2: DS.attr('number'), 
    prop3: DS.attr('my-object') 
} 

Если Transform объект настроен для обработки сериализации/десериализации:

App.MyObjectTransform = DS.Trnasform.extend({ 
    deserialize: function(serialized) { 
     return App.MyObject.create(serialized) 
    }, 
    deserialize: function(deserialized) { 
     return deserialized; 
    } 
} 

Таким образом, когда я работаю с MyModel в рулевом шаблоне я могу сделать что-то вроде:

{{prop1}} 
{{prop2}} 
{{#each prop3}} 
    {{key}} = {{value}} 
{{/each}} 

ответ

14

В Ember v2.0.0-beta.1you can use{{each-in}} помощник, который позволяет перебрать ключей объектов и их значений в шаблонах.

Например, образец объекта:

App.MyObject = Ember.Object.extend({ 
    randomComputedProperty() { 
    return 'foobar'; 
    }  
}); 

конкретизированных таким образом:

let $object = App.MyObject.create({ 
    prop1: 'value1', 
    prop2: 'value2', 
    prop3: ['element1', 'element2'] 
}); 

и итерации в шаблоне с помощью {{each-in}} помощника:

{{#each-in $object as |key value|}} 
    `{{key}}`:`{{value}}` 
{{/each-in}} 

Производит следующие результаты:

`prop1`:`value1` 
`prop2`:`value2` 
`prop3`:`element1,element2` 

JSBin demonstrating this.

Стоит отметить, что с помощью {{each-in}} помощника:

является один раз снимок взгляд на объект, он не будет наблюдать свойства добавляются/удаляются/изменяются.

Спасибо @ Kingpin2k за это указание. Demo, обратите внимание, что обновление до prop1 не отражено в DOM.

+1

Следует отметить, что это одноразовый снимок, который будет отображаться на объекте, он не будет наблюдать добавление/удаление/изменение свойств. – Kingpin2k

+0

Ответ обновлен. –

8

Вот некоторые идеи.

объекта Метод Ключи 1

Вы можете итерацию по свойствам и отфильтровать ключи от цепи прототипов (с использованием the hasOwnProperty() method): Метод Ключи

var obj = App.MyObject.create({stuff: "stuff!"}); 

var objKeys = [] 
for(var key in obj) { 
    if(obj.hasOwnProperty(key)){ 
    objKeys.push(key); 
    } 
} 
console.log(objKeys); // ['stuff'] 

объекта 2

В новых браузерах вы можете напрямую получить массив свойств объекта, используя the Object.keys() method:

console.log(Object.keys(obj)); // ['stuff'] 

Ember.вычисляемые свойства объекта

Ember обеспечивает способ перебрать вычисленных свойств класса с использованием eachComputedProperty() method

App.MyObject.eachComputedProperty(function(name, meta){ 
    console.log(name, meta); // randomComputedProperty 
}); 

JSBin example demonstrating these methods

Update

на Вы могли бы вычисляемый собственность на ваша модель, которая повторно упорядочивает данные MyObject в массив, который затем может отображаться handleba RS:

App.MyModel = DS.Model.extend({ 
    prop1: DS.attr('string'), 
    prop2: DS.attr('number'), 
    prop3: DS.attr('my-object'), 

    prop3PropertyArray: function(){ 
    var prop3, 
     propertyArray = []; 

    prop3 = this.get('prop3'); 

    for(var key in prop3) { 
     if(prop3.hasOwnProperty(key) && key !== "toString"){ 
     propertyArray.push({key: key, value: prop3.get(key)}); 
     } 
    } 

    return propertyArray; 
    }.property('prop3') 
}); 

Если prop3 содержала:

prop3: App.MyObject.create({ 
    stuff: "stuff!", 
    anotherRandomKey: "more value here" 
}) 

тогда prop3PropertyArray будет:

[ 
    { 
    key: "stuff", 
    value: "stuff!" 
    }, 
    { 
    key: "anotherRandomKey", 
    value: "more value here" 
    } 
] 

, которые затем могут быть отображены в рулях с помощью {{#each}}..{{/each}} помощника:

{{#each item in prop3PropertyArray}} 
    {{item.key}} = {{item.value}}<br> 
{{/each}} 

Updated JSBin example

+0

Хорошо спасибо. Я рассмотрю их. Что вы думаете о том, чтобы просто переключиться с EmberObject на некоторый тип Enumerable? Разве это не помогло бы мне перебирать коллекцию в шаблоне рулей. – ken

+0

Возможно, вы захотите обработать его в контроллере в нечто более легкое для отображения в вашем шаблоне. Рукоятки целенаправленно имеют как можно более минимальную логику, поэтому тяжелый подъем должен выполняться в контроллере. – CraigTeegarden

+0

Ну, этот объект является результатом сериализации одного из свойств модели. В идеале я мог бы просто ссылаться на свойства как '{{#each MyObject}} {{key}} = {{value}} {{each}}' в шаблоне. – ken

Смежные вопросы