对EmberJS物体的反思?如何在不事先知道密钥的情况下查找属性键列表

时间:2012-02-09 13:36:32

标签: ember.js

如果您事先不知道所有密钥,有没有办法检索EmberJS对象的set-at-creations属性?

通过检查器,我看到所有对象属性似乎都存储在元对象的values哈希中,但我似乎无法找到任何方法来恢复它。例如object.getProperties()需要一个密钥列表,但我试图创建一个通用对象容器,它不会提前知道它将包含什么,但能够返回有关自身的信息。

8 个答案:

答案 0 :(得分:25)

我没有在生产代码中使用过这个,所以你的里程可能会有所不同,但是查看Ember来源会提出两个可能对你有用的功能,或者至少值得一看:

Ember.keys:“返回在对象或散列上定义的所有键。这在检查对象进行调试时非常有用。在支持它的浏览器上,这使用本机Object.keys实现。” Object.keys documentation on MDN

Ember.inspect:“检查对象的便捷方法。此方法将尝试将对象转换为有用的字符串描述。” Source on Github

答案 1 :(得分:5)

我相信简单的答案是:你找不到道具清单。至少我没能。

但是我注意到ember道具似乎带有前缀__ember,这让我解决了这个问题:

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

它似乎有效。但我不知道是否100%肯定不会得到任何不好的道具。

编辑:亚当的要点来自评论。 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;
}

答案 2 :(得分:5)

遗憾的是,这些答案都不可靠,因为任何与nullundefined值配对的密钥都不可见。

e.g。

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

只会给你

["_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)});

使用此方法,您现在可以访问__keys字段并知道要迭代的键。然而,这不能解决事先不知道结构的物体的问题。

答案 3 :(得分:5)

我用这个:

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

答案 4 :(得分:1)

这些答案都不适用于我。我已经有了Ember Data的解决方案,我只是在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);
    }
};

答案 5 :(得分:0)

我正在尝试做类似的事情,即渲染模型数据行的通用表,以显示给定模型类型的每个属性的列,但让模型描述自己的字段。

如果您使用的是Ember Data,那么这可能有所帮助: http://emberjs.com/api/data/classes/DS.Model.html#method_eachAttribute

您可以迭代模型类型的属性并获取与每个属性关联的元数据。

答案 6 :(得分:0)

这对我有用(来自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')

答案 7 :(得分:0)

在我的情况下Ember.keys(someObject)工作(没有someObject.toJSON()