ember.js - template - ember tutorial
Reflexión sobre los objetos EmberJS? Cómo encontrar una lista de claves de propiedad sin conocer las claves de antemano (8)
¿Hay alguna manera de recuperar las propiedades de set-at-creations de un objeto EmberJS si no conoce todas sus claves por adelantado?
A través del inspector veo todas las propiedades del objeto que parecen estar almacenadas en el hash de values
del metaobjeto, pero parece que no puedo encontrar ningún método para recuperarlo. Por ejemplo, object.getProperties()
necesita una lista de claves, pero estoy tratando de crear un contenedor de objetos genérico que no sepa qué contendrá de antemano, pero puede devolver información sobre sí mismo.
Creo que la respuesta simple es: no encuentras una lista de accesorios. Al menos no he podido.
Sin embargo, noté que los accesorios de las brasas parecen tener el prefijo __ember
, lo que me hizo resolverlo así:
for (f in App.model) {
if (App.model.hasOwnProperty(f) && f.indexOf(''__ember'') < 0) {
console.log(f);
}
};
Y parece funcionar. Pero no sé si es 100% seguro de no obtener ningún accesorio malo.
EDITAR: la esencia de Adam se proporciona a partir de los comentarios. 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;
}
En mi caso, Ember.keys(someObject)
funcionó (sin hacer someObject.toJSON()
.
Esto funcionó para mí (desde 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'')
Estoy tratando de hacer algo similar, es decir, presentar una tabla genérica de filas de datos de modelos para mostrar columnas para cada atributo de un tipo de modelo dado, pero dejar que el modelo describa sus propios campos.
Si está utilizando Ember Data, esto puede ayudar: http://emberjs.com/api/data/classes/DS.Model.html#method_eachAttribute
Puede iterar los atributos del tipo de modelo y obtener metadatos asociados con cada atributo.
Ninguna de esas respuestas funcionó conmigo. Ya tenía una solución para Ember Data, estaba justo después de una para Ember.Object. Encontré que lo siguiente funciona bien. (Elimine Ember.getProperties
si solo quiere las claves, no un hash con clave / valor.
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);
}
};
Ninguna de estas respuestas es confiable, desafortunadamente, porque cualquier clave emparejada con un valor null
o undefined
no será visible.
p.ej
MyClass = Ember.Object.extend({
name: null,
age: null,
weight: null,
height: null
});
test = MyClass.create({name: ''wmarbut''});
console.log( Ember.keys(test) );
Solo te va a dar
["_super", "name"]
La solución que se me ocurrió es:
/**
* 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)});
Al usar este método, ahora puede acceder al campo __keys
y saber qué teclas debe iterar. Sin embargo, esto no resuelve el problema de los objetos donde la estructura no se conoce de antemano.
No he utilizado esto en el código de producción, por lo que su kilometraje puede variar, pero revisar la fuente de Ember sugiere dos funciones que pueden ser útiles para usted, o al menos vale la pena revisar la implementación:
Ember.keys
: "Devuelve todas las claves definidas en un objeto o hash. Esto es útil cuando se inspeccionan objetos para la depuración. En los navegadores que lo admiten, esto utiliza la implementación Object.keys nativa". Documentación de Object.keys en MDN
Ember.inspect
: "Método de conveniencia para inspeccionar un objeto. Este método intentará convertir el objeto en una descripción de cadena útil". Fuente en Github
Yo uso esto:
Ember.keys(Ember.meta(App.YOUR_MODEL.proto()).descs)