Aurelia 的带有对象的 computedFrom
Aurelia's computedFrom with an object
我有一个 state
对象,它有一个 属性 session
,这个 属性 可以是 object
或 null
。
我不想对 isSessionActive()
getter 进行脏检查,所以我想使用 computedFrom()
。但是,computerFrom()
似乎不会在此对象更改时触发,除非它之前是 undefined
。
如果我的 state Store 没有专用的 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;
}
}
我最后做了以下事情:
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')
就像我已经解释过的那样 here,Aurelia 变化检测的工作方式是当 Aurelia 参与观察某些值时,它会设置自定义 getter 和 setters 来代替相应的字段或 属性。基本上,setter 所做的是调用原始 属性 setter(或设置原始支持字段),然后通知任何相关方(即绑定到 [=83= 的任何内容) ]) 值已更改。
没关系,如果这对您来说没有意义,重要的是无论何时绑定到某物,都必须在设置绑定之前 .就像在的评论部分解释的那样,如果你这样写:
private state: State;
这只是对 TypeScript 的提示,即 state
在定义 class 上语义正确。换句话说,因为你没有将它设置为任何东西,它完全被排除在转译的 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
的值 - 所以它 确实存在 ,它恰好具有 [=22] 的值=].后一种情况 确实允许 Aurelia 在属性上设置其自定义逻辑,而前一种情况则没有。
总而言之,要使您的计算 属性 正常工作,您需要做的就是将默认值(例如 undefined
、null
)分配给 计算中涉及的所有属性。无论如何,这是一个很好的做法。
我有一个 state
对象,它有一个 属性 session
,这个 属性 可以是 object
或 null
。
我不想对 isSessionActive()
getter 进行脏检查,所以我想使用 computedFrom()
。但是,computerFrom()
似乎不会在此对象更改时触发,除非它之前是 undefined
。
如果我的 state Store 没有专用的 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;
}
}
我最后做了以下事情:
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')
就像我已经解释过的那样 here,Aurelia 变化检测的工作方式是当 Aurelia 参与观察某些值时,它会设置自定义 getter 和 setters 来代替相应的字段或 属性。基本上,setter 所做的是调用原始 属性 setter(或设置原始支持字段),然后通知任何相关方(即绑定到 [=83= 的任何内容) ]) 值已更改。
没关系,如果这对您来说没有意义,重要的是无论何时绑定到某物,都必须在设置绑定之前 .就像在
private state: State;
这只是对 TypeScript 的提示,即 state
在定义 class 上语义正确。换句话说,因为你没有将它设置为任何东西,它完全被排除在转译的 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
的值 - 所以它 确实存在 ,它恰好具有 [=22] 的值=].后一种情况 确实允许 Aurelia 在属性上设置其自定义逻辑,而前一种情况则没有。
总而言之,要使您的计算 属性 正常工作,您需要做的就是将默认值(例如 undefined
、null
)分配给 计算中涉及的所有属性。无论如何,这是一个很好的做法。