如果我有一组嵌套的普通旧javascript对象(例如,从JSON返回),我如何将它们导入Ember.js对象(或者至少使绑定功能正常工作)?
例如,如果我有一个像这样的对象:
var x = {
bar: {
baz: "quux"
}
}
然后我把它变成一个Ember对象:
var y = Ember.Object.create(x);
然后设置“baz”的值不会更新我拥有的任何视图,因为它只是一个普通的js对象,而不是Ember对象。
我知道我可以递归地遍历对象键,并一直向下执行Ember.Object.create,但是有另一种方法吗?
答案 0 :(得分:2)
在您创建baz
之后,我不确定您是如何尝试设置Ember.Object
的值,但是您应该确保使用支持观察者的setter函数。对于此示例,我建议使用setPath()
。
例如:
var x = {
bar: {
baz: "quux"
}
};
var y = Ember.Object.create(x);
y.setPath('bar.baz', 'foo');
jsFiddle示例,在设置后显示视图更新:http://jsfiddle.net/ebryn/kv3cU/
答案 1 :(得分:0)
出于某种原因,我必须独立定义嵌套对象,以确保计算的工作正常(即使是枚举的)。
为此我最终制作了这两个实用功能:
import EmberObject from '@ember/object';
import { A } from '@ember/array';
function fromArrayToEmberArray(array) {
const emberArray = A();
array.forEach(function(item) {
if (Array.isArray(item)) {
emberArray.push(fromArrayToEmberArray(item));
} else if (item && typeof item === 'object') {
emberArray.push(fromObjectToEmberObject(item));
} else {
emberArray.push(item);
}
});
return emberArray;
}
function fromObjectToEmberObject(pojo) {
const emberObject = EmberObject.create();
for (const key in pojo) {
const keyObject = pojo[key];
if (Array.isArray(keyObject)) {
emberObject.set(key, fromArrayToEmberArray(keyObject))
} else if (keyObject && typeof keyObject === 'object') {
emberObject.set(key, fromObjectToEmberObject(keyObject))
} else {
emberObject.set(key, keyObject);
}
}
return emberObject;
}
export default {fromObjectToEmberObject};
答案 2 :(得分:0)
这是我的版本:
import { typeOf } from '@ember/utils'
import EmberObject from '@ember/object'
export default function deepEmberObject(anything) {
if (typeOf(anything) === 'array') {
return anything.map(a => deepEmberObject(a))
} else if (typeOf(anything) === 'object') {
let converted = Object.keys(anything).reduce((acc, k) => {
acc[k] = deepEmberObject(anything[k])
return acc
}, {})
return EmberObject.create(converted)
} else {
return anything
}
}
测试:
import deepEmberObject from 'zipbooks/utils/deep-ember-object'
import { module, test } from 'qunit'
module('Unit | Utility | deep-ember-object', function() {
test('it works', function(assert) {
let result = deepEmberObject({ pandas: [{ id: 3, children: [{ name: 'Bobby', features: { weight: 3 } }] }] })
assert.equal(
result
.get('pandas')[0]
.get('children')[0]
.get('features')
.get('weight'),
3
)
})
})