是的,你做错了什么,我想你误解了
observable
装饰师和相应的
timeFrameChanged
方法是要使用的。
让我们一点一点地来。请看以下几行:
@observable
timeFrame: TimeFrame = this.state.timeframe;
timeFrameChanged(newValue: TimeFrame, oldValue: TimeFrame) { ... }
这个
可观察到
decorator告诉Aurelia,只要应用它的属性发生更改,就执行相应的方法。除非另有配置,否则相应的方法为
nameOfInvolvedProperty + "Changed"
(在这种情况下,正如您所做的那样,
时间框架已更改
).
但是,您从未真正更改该属性的值!如果您实际更改了该属性,它将起作用:
<button click.delegate="changeProp()">
Change prop
</button>
和虚拟机:
changeProp() {
this.timeFrame = null;
this.timeFrame = this.state.timeframe;
}
现在您将看到处理程序正确地触发。
但在您的代码中,此属性仅分配一次,如下所示:
timeFrame: TimeFrame = this.state.timeframe;
记住,这只是取消引用。换句话说,此代码告诉应用程序获取
this.state.timeframe
,存储
暂时的
它在该变量中的值,并忽略
这状态时间框架
. 所以它不会在任何时候更新
这状态时间框架
已更新。
如中所述
documentation
,您可以配置
可观察到
然而,在某种程度上,装饰者,
据我所知
,无法将其配置为观察嵌套属性(或者可能是我不知道如何进行)。
即使有可能,我认为处理这种情况的更干净的方法是使用
event aggregator
. 这使您能够采用订阅机制—每当您感兴趣的值发生更改时,您都会发布一个事件,任何对该更改感兴趣的组件都可以订阅该事件并相应地更新自身。
一个简单的实现:
import { Router, RouterConfiguration } from 'aurelia-router';
import { autoinject } from 'aurelia-framework';
import { observable } from 'aurelia-binding';
import { StateContainer } from './state-container';
import { EventAggregator, Subscription } from 'aurelia-event-aggregator';
@autoinject
export class App {
subscription: Subscription = null;
constructor(private state: StateContainer, private eventAggregator: EventAggregator) {
}
activate() {
this.subscription = this.eventAggregator.subscribe('state:timeframe', (e) => {
console.log('Timeframe changed!', e);
});
}
deactivate() {
// Make sure to dispose of the subscription to avoid memory leaks.
this.subscription.dispose();
}
change() {
this.state.setTimeframe(new Date(), new Date());
}
}
和
StateContainer
:
import { TimeFrame } from "./time-frame";
import { autoinject } from "aurelia-framework";
import { EventAggregator } from "aurelia-event-aggregator";
@autoinject
export class StateContainer {
public timeframe: TimeFrame = null;
constructor(private eventAggregator: EventAggregator) {
}
public setTimeframe(startTime: Date, endTime: Date) {
// treat this.timeframe as immutable
this.timeframe = { startTime: startTime, endTime: endTime };
this.eventAggregator.publish('state:timeframe', this.timeframe);
}
}
希望这有帮助。