web-dev-qa-db-ja.com

EmberJSオブジェクトについての考察?事前にキーを知らなくてもプロパティキーのリストを見つける方法

すべてのキーが事前にわからない場合に、EmberJSオブジェクトのset-at-creationsプロパティを取得する方法はありますか?

インスペクターを介して、メタオブジェクトのvaluesハッシュに格納されているように見えるすべてのオブジェクトのプロパティを確認しましたが、それを取り戻すためのメソッドが見つからないようです。たとえば、object.getProperties()にはキーリストが必要ですが、何が含まれるかを事前に知らないが、それ自体に関する情報を返すことができる汎用オブジェクトコンテナを作成しようとしています。

23
Seb Barre

私はこれを本番コードで使用していないので、マイレージは異なる場合がありますが、Emberソースを確認すると、役立つ可能性がある、または少なくとも実装を確認する価値のある2つの関数が提案されます。

Ember.keys: "オブジェクトまたはハッシュで定義されたすべてのキーを返します。これは、デバッグのためにオブジェクトを検査するときに役立ちます。これをサポートするブラウザーでは、ネイティブのObject.keys実装を使用します。" MDNに関するObject.keysドキュメント

Ember.inspect: "オブジェクトを検査するための便利なメソッド。このメソッドは、オブジェクトを有用な文字列の説明に変換しようとします。" Githubのソース

25
Luke Melia

私はこれを使用します:

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

簡単な答えは、小道具のリストが見つからないということだと思います。少なくとも私はできませんでした。

しかし、ember小道具の前に__emberが付いているように見えるので、次のように解決しました。

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

そしてそれはうまくいくようです。しかし、悪い小道具を受け取らないことが100%確実かどうかはわかりません。

編集:アダムの要点はコメントから提供されます。 https://Gist.github.com/181754

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;
}
5
Martin Algesten

残念ながら、これらの回答はどちらも信頼できません。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フィールドにアクセスして、反復するキーを知ることができます。ただし、これでは、構造が事前にわからないオブジェクトの問題は解決されません。

5
wmarbut

私の場合、Ember.keys(someObject)は、someObject.toJSON()を実行せずに機能しました。

1
Nelu

それらの答えはどれも私にはうまくいきませんでした。私はすでにEmber Dataの解決策を持っていました、私はEmber.Objectの解決策の直後でした。次のことがうまく機能することがわかりました。(Remove 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);
    }
};
1
Miguel Madero

同様のことをしようとしています。つまり、モデルデータの行の汎用テーブルをレンダリングして、特定のモデルタイプの各属性の列を表示しますが、モデルに独自のフィールドを記述させます。

Ember Dataを使用している場合、これが役立つ場合があります: http://emberjs.com/api/data/classes/DS.Model.html#method_eachAttribute

モデルタイプの属性を繰り返し、各属性に関連付けられたメタデータを取得できます。

0
macu

これは私のために働いた(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')
0
lgrassini