2013-10-12 4 views
9

J'ai Ember.Object qui est utilisé comme dictionnaire de clé/valeur de base. Les noms des clés sont dynamiques et ce que j'aimerais pouvoir faire, c'est parcourir ces propriétés. On dirait que cela devrait être facile, mais google recherches et mon grattage de tête collective ne semble pas pointer vers la réponse évidente que je m'attendais.Itération via un objet Ember

Pour le code psuedo suivant:

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

Ma solution idéale résoudrait pour ce code me permettrait de discerner rapidement:

  • critique: un tableau de noms de propriétés que object a
  • Idéalement: un tableau de noms de propriété calculés que object a
  • Glaçage sur le dessus: un tableau de calcul propriétés ed qui incluent setters le long getter

Avez-vous des idées?

----- ----- MISE A JOUR

Pour être un peu plus explicite au sujet de mon cas d'utilisation précis. Le MyObject fictif est en fait une propriété qui vient d'un de mes modèles:

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

Lorsqu'un objet Transform est configuré pour gérer sérialisation/désérialisation:

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

De cette façon, quand je travaille avec MyModel dans un modèle de guidon, je peux faire quelque chose comme:

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

Répondre

14

Dans Ember v2.0.0-beta.1you can use aide {{each-in}}, qui vous permet d'itérer sur des clés d'objet et leurs valeurs dans vos modèles.

Par exemple, objet exemple:

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

instancié cette façon:

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

Et itéré dans le modèle en utilisant {{each-in}} aide:

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

produit des résultats suivants:

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

JSBin demonstrating this.

Il vaut la peine de mentionner que l'utilisation {{each-in}} aide:

est un regard instantané d'une fois à l'objet, il ne sera pas observer les propriétés ajoutés/supprimés/modifiés.

Merci @ Kingpin2k pour le signaler. Demo, notez que la mise à jour vers prop1 n'est pas répercutée dans le DOM.

+1

Il convient de mentionner qu'il s'agit d'un instantané de vue unique sur l'objet, il ne sera pas observer les propriétés ajoutées/supprimées/modifiées. – Kingpin2k

+0

Réponse mise à jour. –

8

Voici quelques idées.

méthode de l'objet Clés 1

Vous pouvez itérer sur les propriétés et filtrer les clés de la chaîne de prototype (en utilisant 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'] 

méthode de l'objet Clés 2

Sur les nouveaux navigateurs, vous pouvez obtenir directement un tableau des propriétés de l'objet en utilisant the Object.keys() method:

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

Ember.de l'objet de propriétés calculées

Ember offre un moyen d'itérer sur les propriétés calculées d'une classe en utilisant la eachComputedProperty() method

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

JSBin example demonstrating these methods

Mise à jour

Vous pourriez avoir une propriété calculée sur votre modèle qui réorganise les données de MyObject en un tableau qui peut ensuite être affiché par 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') 
}); 

Si prop3 contient:

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

alors prop3PropertyArray serait:

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

qui peut ensuite être affiché dans le guidon à l'aide d'un assistant {{#each}}..{{/each}}:

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

Updated JSBin example

+0

Ok merci. Je vais regarder dans ceux-ci. Que pensez-vous de simplement passer d'un EmberObject à un type Enumerable? Cela ne m'aiderait-il pas à parcourir la collection dans un modèle de guidon. – ken

+0

Vous voudrez probablement le traiter dans un contrôleur en quelque chose de plus facile à afficher dans votre modèle. Handlebars a délibérément une logique aussi minimale que possible, de sorte que le levage lourd doit être fait dans un contrôleur. – CraigTeegarden

+0

Eh bien, cet objet est le résultat de la sérialisation de l'une des propriétés du modèle. Idéalement, je pourrais juste référencer les propriétés comme '{{#each MyObject}} {{key}} = {{value}} {{/ each}}' dans un modèle. – ken

Questions connexes