我有一个变量,可以随时存储可用的汽车。有没有一种方法可以在每次更改时自动重新评估此功能?
在这种情况下仅使用this.carFactory.available不是解决方案,因为我正在演示的这个示例已简化-项目中的实际计算要复杂得多。
calculateAvailableCars(){
this.carFactory.available.forEach(function(item){
this.availableCars.push(car.id);
}.bind(this));
}
我如何在Angular 2中做到这一点?在Angular JS中,可以$ watch一个函数。
我当然可以在每次更改时手动调用此函数,但是最好不必在应用程序的每个可以更改数据的部分调用此函数。
答案 0 :(得分:2)
您可以在模板上使用此函数输出:
carOutput(): cars[] {
this.calculateAvailableCars()
return this.availableCars;
}
并在模板上使用输出:
<p>My car ratio is {{ carOutput() }} </p>
但是,这将触发对该变量非常积极的更改检测策略。这个解决方案是最简单的,但是从工程角度来看却是最糟糕的:消耗大量不必要的函数调用。需要注意的是,必须不设置主机元素才能检测到更改onPush
。
您可以将汽车列表显示存储在单独的组件中,并将新的汽车数组作为输入属性传递到此组件:
<car-display [cars]="availableCars"></car-display>
然后,您可以将此组件中的changeDetetcion
策略设置为onPush
,并且每次将绑定到availableCars
的输入属性更改时,<car-display>
将重新呈现。
如果某些外部主机操作触发了新车计算,那么hostBinding
可能会有所帮助:
@hostListener(`hover`) recalculateCars() {
this.calculateAvailableCars()
}
最后,(因为您用保密的方式描述了用例,没有太多细节,因此我正在讨论所有可能的方案)如果某些外部组件操作将触发重新计算,则可以使用ngLifecycle
{ {1}}例如,如果外部输入属性更改将重新触发汽车计算。
换句话说,所有这些加起来,取决于触发变更的人员和来源,然后重新触发可用的汽车重新计算。
非常重要,请参阅@ chiril.sarajiu的答案,因为我们在此处尝试解决的问题可以由单个可观察对象自动处理。这需要额外的设置(服务,例如可观察到的组件),但这是值得的。
---编辑---
正如OP所阐明的那样,更改与绑定到组件的模型有关。因此,@ marvstar提到的另一个选项是使用ngOnChanges()
,其中每个模型变量的更改都会重新触发获取函数:
set
答案 1 :(得分:1)
您需要RxJS。您要做的是创建一个数据服务,该数据服务将存储一个Observable(在我的情况下,是BehaviorSubject,这几乎是相同的,但在我的情况下,我从一个值开始)。
export class DataService {
private dataStorage$ = new BehaviorSubject(null); //here is the data you start with
get getDataStorage() {
return this.dataStorage$.asObservable(); // so you won't be able to change it outside the service
}
set setDataStorage(data: any) {
this.dataStorage$.next(data);
}
}
然后,您订阅该数据的位置将发生变化,
constructor(private dataService: DataService){}
ngOnInit() {
this.dataService.getDataStorage.subscribe((data) => this.calculateAvailableCars(data));
}
calculateAvailableCars(){
this.carFactory.available.forEach(function(item){
this.availableCars.push(car.id);
}.bind(this));
}
阅读有关在Angular中使用RxJS的最佳实践的更多信息,因为可能会有很多陷阱和问题。
答案 2 :(得分:0)
尝试使用setter和getter。
private _YourVariable:any;
public set YourVariable(value:any){
this._YourVariable = value;
//do your logik stuff here like. calculateAvailableCars
}
public get YourVariable():any{
return this._YourVariable ;
}