我有一个 state
对象,它有一个属性 session
,这个属性可以是一个 object
或 null
.
我不想对 isSessionActive()
getter 进行脏检查,所以我想使用 computedFrom()
。但是,computerFrom()
似乎不会在该对象更改时触发,除非它之前是 undefined
。
如果我的 state Store 没有专用的 isSessionActive
bool 属性,我可以这样做吗?
@autoinject
export class Home {
firstName: string = "user";
private state: State;
constructor(private store: Store) {
store.state.subscribe(
response => this.state = response
)
}
@computedFrom('state.activeSession')
get isSessionActive() {
return this.state.activeSession !== null;
}
}
最佳答案
我可以看到您已经解决了您的问题,但它更像是一种解决方法,而不是实际的解决方案。因此,我想就您为什么会遇到这种情况以及如何解决它提出一些解释。基本上,您的问题几乎是描述的同一问题的不同情况 here .
我在评论区给出了详细的解释,因为有猜测答案,所以我在这里重复一遍。
重要的代码是这些:
private state: State;
// ...
@computedFrom('state.activeSession')
就像我已经解释过的那样here ,Aurelia 变化检测的工作方式是,当 Aurelia 参与观察某些值时,它会设置自定义 getter 和 setter 来代替相应的字段或属性。基本上, setter 所做的是调用原始属性 setter (或设置原始支持字段),然后通知任何相关方(即绑定(bind)到该属性的任何对象)值已更改。
如果这对您来说没有意义,请不要介意,重要的是无论何时绑定(bind)到某物,必须在绑定(bind)设置之前就已经到位。就像在 linked answer 的评论部分中解释的那样,如果你这样写:
private state: State;
这只是对 TypeScript 的提示,即 state
在定义类上的语义是正确的。换句话说,因为您没有将它设置为任何东西,它完全被排除在转译的 JavaScript 代码之外 - 它所做的只是使 state
的用法有效在 TypeScript 中。
例如,如果您这样做:
class A {
x: number;
}
那么生成的 JavaScript 将类似于:
function A() {
}
注意没有this.x
!但是,如果您改为这样写:
class B {
x: number = undefined; // or null, or whatever you like
}
那么生成的 JavaScript 将是:
function B() {
this.x = undefined;
}
两者之间的区别在于,在第一种情况下,没有要绑定(bind)的属性。因此,Aurelia 无法订阅它,因为它无法知道(在 JavaScript 中)该属性何时开始存在于对象上。重要的是要注意,如果您像这样检查控制台中的值:
var a = new A();
var b = new B();
console.log(a.x); // undefined
console.log(b.x); // undefined
a.x
和b.x
似乎都是undefined
。但它们是不同的:a.x
是 undefined
因为它在 a
上不存在,而 b.x
是 undefined
因为它被明确分配了一个值 undefined
- 所以它确实存在,它只是恰好具有 undefined
的值。后一种情况确实能够 Aurelia 在属性上设置其自定义逻辑,而前一种情况则不能。
总而言之,要使您的计算属性起作用,您需要做的就是为所有其计算中涉及的属性。无论如何,这是一个很好的做法。
关于javascript - Aurelia 的带有对象的 computedFrom,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45655865/