Ember.js 对对象的反射?如何在不预先知道键的情况下查找属性键列表
如果您事先不知道所有密钥,是否有方法检索EmberJS对象的set at creations属性Ember.js 对对象的反射?如何在不预先知道键的情况下查找属性键列表,ember.js,Ember.js,如果您事先不知道所有密钥,是否有方法检索EmberJS对象的set at creations属性 通过inspector,我看到所有对象属性似乎都存储在元对象的值散列中,但我似乎找不到任何方法将其取回。例如,object.getProperties()需要一个键列表,但我正在尝试创建一个通用的对象容器,它不知道它将包含什么,但能够返回关于自身的信息。我相信简单的答案是:你找不到一个道具列表。至少我没能做到 然而,我注意到余烬道具的前缀似乎是\uu ember,这让我像这样解决它: for (f
通过inspector,我看到所有对象属性似乎都存储在元对象的
值
散列中,但我似乎找不到任何方法将其取回。例如,object.getProperties()
需要一个键列表,但我正在尝试创建一个通用的对象容器,它不知道它将包含什么,但能够返回关于自身的信息。我相信简单的答案是:你找不到一个道具列表。至少我没能做到
然而,我注意到余烬道具的前缀似乎是\uu ember
,这让我像这样解决它:
for (f in App.model) {
if (App.model.hasOwnProperty(f) && f.indexOf('__ember') < 0) {
console.log(f);
}
};
用于(应用程序模型中的f){
if(App.model.hasOwnProperty(f)和&f.indexOf(“'uu ember'))<0){
控制台日志(f);
}
};
这似乎奏效了。但我不知道是否100%肯定不会得到任何坏的道具
编辑:亚当的要点来自评论
var getOwnProperties=函数(模型){
var props={};
对于(模型中的var prop){
if(型号hasOwnProperty(道具)
&&属性索引(“成员”)<0
&&属性索引(“超级”)小于0
&&Ember.typeOf(model.get(prop))!=“函数”
){
道具[道具]=模型[道具];
}
}
返回道具;
}
我没有在生产代码中使用此功能,因此您的里程数可能会有所不同,但查看Ember源代码会发现两个功能可能对您有用,或者至少值得查看实现:
Ember.keys
:“返回在对象或哈希上定义的所有键。这在检查对象进行调试时非常有用。在支持它的浏览器上,这将使用本机object.keys实现。”
Ember.inspect
:“检查对象的方便方法。此方法将尝试将对象转换为有用的字符串描述。”不幸的是,这两个答案都不可靠,因为与null
或未定义的值配对的任何键都将不可见
e、 g
只会给你
["_super", "name"]
我提出的解决方案是:
/**
* 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)});
使用此方法,您现在可以访问\u keys
字段,并知道要迭代哪些键。然而,这并不能解决以前不知道结构的对象的问题 我用这个:
Ember.keys(Ember.meta(App.YOUR_MODEL.proto()).descs)
我正在尝试做类似的事情,即呈现一个模型数据行的通用表,以显示给定模型类型的每个属性的列,但让模型描述它自己的字段
如果您使用的是余烬数据,那么这可能会有帮助:
您可以迭代模型类型的属性,并获取与每个属性相关联的元数据。这些答案都不适用于我。我已经有了一个关于余烬数据的解决方案,我刚刚找到了一个关于Ember.Object的解决方案。我发现下面的方法很好用。(如果您只需要键,而不是带有键/值的哈希,请删除Ember.getProperties
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);
}
};
这对我来说很有效(来自ArrayController):
在我的例子中,Ember.keys(someObject)
起作用了,而没有做someObject.toJSON()
我在你的if()语句中添加了(Ember.typeOf(App.model.p)!==“function”)
,这很适合我的需要,但似乎已经足够了。我会等一会儿,看看是否有人提供了一个更“正确”的版本(因为你说得对,这似乎有点脆弱),如果没有更好的办法,我会接受。我上面的评论中有一个错误。。应该是(Ember.typeOf(App.model.get(p))!=“function”)
将Seb Barre的简单函数转换为Ember.Object.prototype上的函数不幸的是,使用hasOwnProperty拒绝属性只会让我们在create()中定义属性方法。这意味着我们在模型中声明的任何默认属性都不会返回。删除这些属性会留下额外的属性,例如我们不需要的“isInstance”。可以查看更新的示例。我已将其稍作更改,以使用getProperties检索属性。就我而言,isInstance不是问题,因此我将如果需要,请进一步改进。proto似乎不再是一个工作函数。相反,您可以使用toJSON:Ember.keys(modelObject.toJSON())
Ember.inspect不会忽略以下划线开头的键。与github.com/NV/jsdump这样的东西相比,它相当简单。现在它给出了一个弃用通知Ember.debug.js:5549弃用:Ember.keys被弃用,取而代之的是Object.keys[弃用id:Ember metal.Ember.keys]
Ember.keys(Ember.meta(App.YOUR_MODEL.proto()).descs)
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);
}
};
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')