如何将嵌套的普通js对象转换为Ember.js对象?

时间:2012-01-12 16:05:45

标签: javascript ember.js

如果我有一组嵌套的普通旧javascript对象(例如,从JSON返回),我如何将它们导入Ember.js对象(或者至少使绑定功能正常工作)?

例如,如果我有一个像这样的对象:

var x = {
  bar: {
    baz: "quux"
  }
}

然后我把它变成一个Ember对象:

var y = Ember.Object.create(x);

然后设置“baz”的值不会更新我拥有的任何视图,因为它只是一个普通的js对象,而不是Ember对象。

我知道我可以递归地遍历对象键,并一直向下执行Ember.Object.create,但是有另一种方法吗?

3 个答案:

答案 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
    )
  })
})