我有一个state
对象,其属性为session
,此属性可以是object
或null
。
我不想弄脏isSessionActive()
getter,所以我想使用computedFrom()
。但是,computerFrom()
似乎无法在此对象发生变化时触发,除非之前为undefined
。
我可以在我的州商店中没有专用的isSessionActive
布尔属性吗?
@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;
}
}
答案 0 :(得分:2)
我最终只是做了以下事情:
isSessionActive: boolean = false;
constructor(private store: Store) {
store.state.subscribe(
response => {
this.state = response;
this.isSessionActive = response.activeSession !== null;
}
)
}
答案 1 :(得分:1)
我可以看到你已经解决了你的问题,但这是一个解决方法,而不是一个实际的解决方案。因此,我想提出一些解释,说明为什么要体验这一点以及如何解决它。基本上,您的问题与here描述的同一问题几乎不同。
我在评论部分提供了一个详细的解释,因为有一个猜测答案,所以我将在这里重复一遍。
代码的重要部分是:
private state: State;
// ...
@computedFrom('state.activeSession')
就像我已经解释过here一样,Aurelia更改检测的方式是,当Aurelia参与观察某些值时,它会设置自定义的getter和setter来代替相应的字段或属性。基本上,setter所做的是调用原始属性设置器(或设置原始支持字段),然后通知任何感兴趣的各方(即,与该属性绑定的任何内容)该值已更改。
没关系,如果这对你没有意义,重要的是每当你绑定某些东西时,必须在之前设置某些内容之前设置绑定。就像在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;
}
两者之间的区别在于,在第一种情况下,没有要绑定的属性。因此,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
的值 - 因此确实存在,它恰好具有值undefined
。后一种情况确实启用了 Aurelia在属性上设置自定义逻辑,而前者则没有。
总之,为了使您的计算属性有效,您需要做的就是为所有属性分配一个默认值(例如null
,com.sun.javafx.geom.Rectangle
)参与其计算。无论如何,这是一个很好的做法。