Javascript 奥雷利亚';它是用一个对象计算出来的
我有一个Javascript 奥雷利亚';它是用一个对象计算出来的,javascript,typescript,aurelia,Javascript,Typescript,Aurelia,我有一个状态对象,它有一个属性会话,这个属性可以是对象或空 我不想对isSessionActive()getter进行脏检查,所以我想使用computedFrom()。但是,当此对象更改时,computerFrom()似乎不会激发,除非它以前未定义 在我的状态存储上没有专用的isSessionActiveboolean属性,我可以这样做吗 @autoinject export class Home { firstName: string = "user"; private sta
状态
对象,它有一个属性会话
,这个属性可以是对象
或空
我不想对isSessionActive()
getter进行脏检查,所以我想使用computedFrom()
。但是,当此对象更改时,computerFrom()
似乎不会激发,除非它以前未定义
在我的状态存储上没有专用的isSessionActive
boolean属性,我可以这样做吗
@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;
}
}
我最后只是做了以下几件事:
isSessionActive: boolean = false;
constructor(private store: Store) {
store.state.subscribe(
response => {
this.state = response;
this.isSessionActive = response.activeSession !== null;
}
)
}
我可以看出你已经解决了你的问题,但这是一个变通办法,而不是实际的解决办法。因此,我想提出一些解释,解释一下你为什么会遇到这种情况,以及如何解决它。基本上,你的问题与所描述的同一个问题是完全不同的 我在评论部分提供了一个详细的解释,因为有一个猜测答案,所以我将在这里重复我自己
重要的代码位如下:
private state: State;
// ...
@computedFrom('state.activeSession')
正如我已经解释过的,Aurelia变更检测的工作方式是,当Aurelia参与观察某个值时,它会设置自定义的getter和setter来代替相应的字段或属性。基本上,setter所做的是调用原始属性setter(或设置原始支持字段),然后通知任何相关方(即绑定到该属性的任何方)值已更改
如果这对你来说没有意义,那也没关系。重要的是,每当你绑定到某个东西时,在绑定设置之前,某个东西必须就位。如在的评论部分所述,如果您写下以下内容:
private state: State;
这只是对TypeScript的一个提示,state
在定义类上语义正确。换句话说,由于您没有将其设置为任何值,它被完全排除在传输的JavaScript代码之外——它所做的只是使状态的使用在TypeScript中有效
例如,如果您这样做:
class A {
x: number;
}
然后生成的JavaScript将类似于:
function A() {
}
请注意,没有此.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
似乎都是未定义的
。但是它们是不同的:a.x
是未定义的
,因为它在a
上不存在,而b.x
是未定义的
,因为它被显式地分配了一个值未定义的
,所以它确实存在,只是碰巧有一个值未定义的
。后一种场景确实允许Aurelia在属性上设置其自定义逻辑,而前一种场景则不允许
总之,要使计算的属性正常工作,只需为其计算中涉及的所有属性指定一个默认值(例如undefined
,null
)。无论如何,这是一个很好的做法。也许这会有所帮助,因为我已经订阅了我商店的状态。我可以简单地触发回调事件并手动更新getter,但它没有那么干净。我认为应该设置state.activeSession
,而不是将对象替换为this.state=response
。您所拥有的应该可以工作,但它只会在state.activeSession
更改时调用getter,如果state.activeSession.foo
发生更改,则不会更改。它只会注意到整个对象何时被调出,而不会注意到对象上的属性何时发生更改。对,这就是我在@AshleyGrant看到的,以及我在其他地方用@observable
和@computedFrom
观察到的。这是令人失望的。看到我上面的答案,我可能会像你在这个答案中那样完成这项工作,因为它的代码更少,但是你可以在getter上使用@computedFrom('state
)`来完成。谢谢,这很有意义。这是较少的代码,但我觉得不太干净。我想这只是我的感觉。谢谢,这提供了很多背景。