如何使Ember计算的属性依赖于变量的所有后代属性?

时间:2019-05-20 21:58:53

标签: javascript ember.js

我试图创建一个计算属性,只要深度嵌套对象中的任何值发生更改,我都希望重新计算该属性。我知道myObj.[]可用于在数组中的任何对象发生更改时重新评估计算的属性,但是我希望这是递归的。

例如我有

// should recalculate whenever myObj.x.y.z changes, or when myObj.a.b.c changes
computed('myObj', function() {
  // ...
})

我不知道对象的确切结构,它可能很深。

computed('myObj.[]', ...)computed('myObj.@each', ...)似乎都不适合这样做。

任何想法如何做到这一点?

2 个答案:

答案 0 :(得分:1)

在Ember中,可以在运行时定义计算的属性

import { defineProperty, computed } from '@ember/object';

// define a computed property
defineProperty(myObj, 'nameOfComputed', computed('firstName', 'lastName', function() {
  return this.firstName+' '+this.lastName;
}));

因此,更进一步,您可以在运行时动态创建所需的任何计算出的属性键字符串(可以在组件的init()中):

// define a computed property
let object = {
   foo: 'foo',
   bar: 'bar'
}
this.set('myObj', object);
let keys = Object.keys(object).map((key) => {
  return `myObj.${key}`
});
defineProperty(this, 'someComputed', computed.apply(this, [...keys, function() {
  // do something here
}]));

由您决定如何正确地递归遍历所有相关键的对象,而无需创建循环或访问您不想要的原型键……还是要考虑这是否对理念。或者,您可以尝试以重新触发计算的方式处理这些属性的设置(这将与DDAU更加一致)。我只能从您提供的内容中推测出什么可行,但是肯定可以做您想要的。参见this twiddle的实际操作

答案 1 :(得分:0)

could you try anyone computed/obeserver like below..
But try to prefer the computed.

import { observer } from '@ember/object';
import EmberObject, { computed } from '@ember/object';

partOfNameChanged1: observer('myObj','myObj.[]','myObj.@each', function() {
  return 'myObj is changed by obeserver';
})

partOfNameChanged2: computed ('myObj','myObj.[]','myObj.@each', function() {
  return 'myObj is changed by computed';
})

then in your handlebar/template file

{{log 'partOfNameChanged1 is occured' partOfNameChanged1}}
{{log 'partOfNameChanged2 is occured' partOfNameChanged2}}

然后,您必须将此partOfNameChanged1 / partOfNameChanged2关联/分配到车把中的某些位置或.js文件中的任何其他变量。 只要您尚未将此计算/观察者属性partOfNameChanged1 /partOfNameChanged2分配给某个地方,就不会得到它的值。