Подтвердить что ты не робот

Отражение объектов EmberJS? Как найти список ключей свойств, не зная заранее ключей

Есть ли способ получить свойства set-at-creations объекта EmberJS, если вы заранее не знаете все свои ключи?

Через инспектора я вижу все свойства объекта, которые, как представляется, хранятся в мета-объекте values хеш, но я не могу найти никаких методов для его возврата. Например, object.getProperties() нужен список ключей, но я пытаюсь создать универсальный контейнер объекта, который не знает, что он будет содержать заранее, но может возвращать информацию о себе.

4b9b3361

Ответ 1

Я не использовал это в производственном коде, поэтому ваш пробег может отличаться, но просмотр источника Ember предлагает две функции, которые могут вам пригодиться, или, по крайней мере, стоит рассмотреть реализацию:

Ember.keys: "Возвращает все ключи, определенные на объекте или хэше. Это полезно при проверке объектов для отладки. В браузерах, которые его поддерживают, используется встроенная реализация Object.keys." Документация Object.keys на MDN

Ember.inspect: "Метод удобства для проверки объекта. Этот метод попытается преобразовать объект в полезное описание строки". Источник на Github

Ответ 2

Я считаю, что простой ответ: вы не найдете список реквизитов. По крайней мере, я не смог.

Однако я заметил, что у ember-реквизита есть префикс __ember, который заставил меня решить его следующим образом:

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

И это работает. Но я не знаю, будет ли он на 100% уверен, чтобы не получить плохих реквизитов.

РЕДАКТИРОВАТЬ: Adam gist предоставляется из комментариев. 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;
}

Ответ 3

Ни один из этих ответов не является надежным, к сожалению, потому что любые клавиши в паре со значением null или undefined не будут видны.

например.

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 и узнать, какие ключи перебираются. Это, однако, не решает проблему объектов, где структура неизвестна раньше.

Ответ 4

Я использую это:

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

Ответ 5

Ни один из этих ответов не работал со мной. У меня уже было решение для 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);
    }
};

Ответ 6

В моем случае Ember.keys(someObject) работал, не делая someObject.toJSON().

Ответ 7

Я пытаюсь сделать что-то подобное, т.е. отобразить общую таблицу строк данных модели для отображения столбцов для каждого атрибута данного типа модели, но пусть модель описывает свои собственные поля.

Если вы используете Ember Data, это может помочь: http://emberjs.com/api/data/classes/DS.Model.html#method_eachAttribute

Вы можете перебирать атрибуты типа модели и получать метаданные, связанные с каждым атрибутом.

Ответ 8

Это сработало для меня (из 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')

Ответ 9

Ember.keys устарел в пользу Object.keys

который также решает проблему, упомянутую wmarbut.