すべてのキーが事前にわからない場合に、EmberJSオブジェクトのset-at-creationsプロパティを取得する方法はありますか?
インスペクターを介して、メタオブジェクトのvalues
ハッシュに格納されているように見えるすべてのオブジェクトのプロパティを確認しましたが、それを取り戻すためのメソッドが見つからないようです。たとえば、object.getProperties()
にはキーリストが必要ですが、何が含まれるかを事前に知らないが、それ自体に関する情報を返すことができる汎用オブジェクトコンテナを作成しようとしています。
私はこれを本番コードで使用していないので、マイレージは異なる場合がありますが、Emberソースを確認すると、役立つ可能性がある、または少なくとも実装を確認する価値のある2つの関数が提案されます。
Ember.keys
: "オブジェクトまたはハッシュで定義されたすべてのキーを返します。これは、デバッグのためにオブジェクトを検査するときに役立ちます。これをサポートするブラウザーでは、ネイティブのObject.keys実装を使用します。" MDNに関するObject.keysドキュメント
Ember.inspect
: "オブジェクトを検査するための便利なメソッド。このメソッドは、オブジェクトを有用な文字列の説明に変換しようとします。" Githubのソース
私はこれを使用します:
Ember.keys(Ember.meta(App.YOUR_MODEL.proto()).descs)
簡単な答えは、小道具のリストが見つからないということだと思います。少なくとも私はできませんでした。
しかし、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;
}
残念ながら、これらの回答はどちらも信頼できません。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
フィールドにアクセスして、反復するキーを知ることができます。ただし、これでは、構造が事前にわからないオブジェクトの問題は解決されません。
私の場合、Ember.keys(someObject)
は、someObject.toJSON()
を実行せずに機能しました。
それらの答えはどれも私にはうまくいきませんでした。私はすでに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);
}
};
同様のことをしようとしています。つまり、モデルデータの行の汎用テーブルをレンダリングして、特定のモデルタイプの各属性の列を表示しますが、モデルに独自のフィールドを記述させます。
Ember Dataを使用している場合、これが役立つ場合があります: http://emberjs.com/api/data/classes/DS.Model.html#method_eachAttribute
モデルタイプの属性を繰り返し、各属性に関連付けられたメタデータを取得できます。
これは私のために働いた(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')