2012-02-09 12 views
22

C'è un modo per recuperare le proprietà di set-at-creations di un oggetto EmberJS se non si conoscono tutte le chiavi in ​​anticipo?Riflesso sugli oggetti EmberJS? Come trovare un elenco di chiavi di proprietà senza conoscere le chiavi in ​​anticipo

Tramite l'ispettore vedo tutte le proprietà dell'oggetto che sembrano essere memorizzate nell'hash values del metaoggetto, ma non riesco a trovare alcun metodo per recuperarlo. Ad esempio, object.getProperties() ha bisogno di un elenco di chiavi, ma sto cercando di creare un contenitore di oggetti generico che non sappia cosa conterrà in anticipo, ma è in grado di restituire informazioni su se stesso.

risposta

24

Non ho usato questo nel codice di produzione, così il vostro chilometraggio può variare, ma rivedendo la fonte Ember suggerisce due funzioni che potrebbero essere utili a voi, o almeno la pena rivedere l'attuazione:

Ember.keys: "Restituisce tutte le chiavi definite su un oggetto o hash .Questo è utile quando si controllano gli oggetti per il debug. Sui browser che lo supportano, questo utilizza l'implementazione Object.keys nativa." Object.keys documentation on MDN

Ember.inspect: "Metodo pratico per ispezionare un oggetto. Questo metodo tenterà di convertire l'oggetto in una descrizione di stringa utile." Source on Github

+0

Ember.inspect non, per esempio, ignora i tasti che iniziano con un trattino di sottolineatura '_'. È piuttosto semplice rispetto a qualcosa come github.com/NV/jsDump –

4

Credo che la semplice risposta sia: non si trova un elenco di oggetti di scena. Almeno non sono stato in grado di farlo.

Tuttavia ho notato che puntelli Ember sembrano essere prefissato __ember, che mi ha fatto a risolvere in questo modo:

for (f in App.model) { 
    if (App.model.hasOwnProperty(f) && f.indexOf('__ember') < 0) { 
     console.log(f); 
    } 
}; 

E sembra funzionare. Ma non so se sia sicuro al 100% di non avere oggetti di scena cattivi.

MODIFICA: l'analisi di Adam viene fornita dai commenti. https://gist.github.com/1817543

var getOwnProperties = function(model){ 
    var props = {}; 
    for(var prop in model){ 
    if(model.hasOwnProperty(prop) 
     && prop.indexOf('__ember') < 0 
     && prop.indexOf('_super') < 0 
     && Ember.typeOf(model.get(prop)) !== 'function' 
    ){ 
     props[prop] = model[prop]; 
    } 
    } 
    return props; 
} 
+0

Ho aggiunto '(Ember.typeOf (App.model.p)! ==" function ")' alla dichiarazione if(), che si adatta alle mie esigenze, ma sembra funzionare abbastanza bene. Aspetterò un po 'per vedere se qualcuno fornisce una versione più "corretta" (dal momento che hai ragione nel dire che questo sembra un po' fragile) e accetterò se non emergerà nulla di meglio. –

+0

C'è un errore nel mio commento sopra .. Dovrebbe essere '(Ember.typeOf (App.model.get (p))! ==" function ")' –

+0

Aggiunti tutti i precedenti a una semplice funzione [qui] (https://gist.github.com/1817543) –

5

Nessuna di queste risposte è affidabile, sfortunatamente, perché qualsiasi tasto associato a un valore null o undefined non sarà visibile.

ad es.

MyClass = Ember.Object.extend({ 
    name: null, 
    age: null, 
    weight: null, 
    height: null 
}); 
test = MyClass.create({name: 'wmarbut'}); 
console.log(Ember.keys(test)); 

è solo andare a dare

["_super", "name"] 

La soluzione che mi è venuto in mente è:

/** 
* Method to get keys out of an object into an array 
* @param object obj_proto The dumb javascript object to extract keys from 
* @return array an array of keys 
*/ 
function key_array(obj_proto) { 
    keys = []; 
    for (var key in obj_proto) { 
     keys.push(key); 
    } 
    return keys; 
} 


/* 
* Put the structure of the object that you want into a dumb JavaScript object 
* instead of directly into an Ember.Object 
*/ 
MyClassPrototype = { 
    name: null, 
    age: null, 
    weight: null, 
    height: null 
} 

/* 
* Extend the Ember.Object using your dumb javascript object 
*/ 
MyClass = Ember.Object.extend(MyClassPrototype); 

/* 
* Set a hidden field for the keys the object possesses 
*/ 
MyClass.reopen({__keys: key_array(MyClassPrototype)}); 

Utilizzando questo metodo, è ora possibile accedere al campo __keys e sapere quali chiavi per iterare sopra. Questo, tuttavia, non risolve il problema degli oggetti in cui la struttura non è conosciuta prima della mano.

5

Io uso questo:

Ember.keys(Ember.meta(App.YOUR_MODEL.proto()).descs) 
+0

.proto non sembra più una funzione di workging. Invece, potresti usare toJSON: 'Ember.keys (modelObject.toJSON());' –

0

che sto cercando di fare qualcosa di simile, vale a dire rendere un tavolo generica di righe di dati del modello per mostrare colonne per ogni attributo di un determinato tipo di modello, ma lasciate che il modello descrivere i propri campi.

Se stai usando Ember dati, quindi questo può aiutare: http://emberjs.com/api/data/classes/DS.Model.html#method_eachAttribute

È possibile scorrere gli attributi del tipo di modello e ottenere i metadati associati a ciascun attributo.

1

Nessuna di quelle risposte ha funzionato con me. Avevo già una soluzione per Ember Data, ne avevo appena uno per Ember.Object. Ho trovato il seguente per funzionare bene. (Rimuovere Ember.getProperties se desideri solo le chiavi, non un hash con chiave/valore

getPojoProperties = function (pojo) { 
    return Ember.getProperties(pojo, Object.keys(pojo)); 
}, 
getProxiedProperties = function (proxyObject) { 
    // Three levels, first the content, then the prototype, then the properties of the instance itself 
    var contentProperties = getPojoProperties(proxyObject.get('content')), 
     prototypeProperties = Ember.getProperties(proxyObject, Object.keys(proxyObject.constructor.prototype)), 
     objectProperties = getPojoProperties(proxyObject); 
    return Ember.merge(Ember.merge(contentProperties, prototypeProperties), objectProperties); 
}, 
getEmberObjectProperties = function (emberObject) { 
    var prototypeProperties = Ember.getProperties(emberObject, Object.keys(emberObject.constructor.prototype)), 
     objectProperties = getPojoProperties(emberObject); 
    return Ember.merge(prototypeProperties, objectProperties); 
}, 
getEmberDataProperties = function (emberDataObject) { 
    var attributes = Ember.get(emberDataObject.constructor, 'attributes'), 
     keys = Ember.get(attributes, 'keys.list'); 
    return Ember.getProperties(emberDataObject, keys); 
}, 
getProperties = function (object) { 
    if (object instanceof DS.Model) { 
     return getEmberDataProperties(object); 
    } else if (object instanceof Ember.ObjectProxy) { 
     return getProxiedProperties(object); 
    } else if (object instanceof Ember.Object) { 
     return getEmberObjectProperties(object); 
    } else { 
     return getPojoProperties(object); 
    } 
}; 
0

Questo ha funzionato per me (da un ArrayController):.

fields: function() { 
    var doc = this.get('arrangedContent'); 

     var fields = []; 
     var content = doc.content; 
     content.forEach(function(attr, value) { 
     var data = Ember.keys(attr._data); 
     data.forEach(function(v) { 
      if(typeof v === 'string' && $.inArray(v, fields) == -1) { 
      fields.push(v); 
      } 
     }); 
     }); 
    return fields; 
    }.property('arrangedContent') 
1

Nel mio caso Ember.keys(someObject) lavorato (senza fare someObject.toJSON().

0

Ember.keys è deprecato in favore di Object.keys

che risolve anche un problema menzionato da wmarbut.

Problemi correlati