我的根页面上有一个组件,它公开了一些可绑定的属性,可以这样使用:
<myprogress [value]="current" [max]="maximum"></myprogress>
在我的应用程序中,各种类型的对象都需要显示进度。所以我创建了一些指令如下:
@Directive({
selector: 'myprogress[order]'
})
export class OrderProgress {
@Input('order') order: Order;
constructor(private baseComponent: Progress) {}
ngOnInit() {
this.baseComponent.value = this.order.currentStage;
this.baseComponent.max = this.order.totalStages;
}
}
这使我可以替换以下呼叫:
<myprogress [value]="order.currentStage" [max]="order.totalStages"></myprogress>
具有更可读性:
<myprogress [order]="order"></myprogress>
在应用程序的某个部分更改顺序之前,此操作可以正常工作。在这种情况下,不更新已经渲染的myprogress
组件。我也明白为什么。ngOnInit
函数在渲染组件时只运行一次,并且无法向指令指示顺序的某些属性已更改,需要计算value
和max
的新值。
有办法解决这个问题吗?
我有一个可能的解决方案:
- 修改
Progress
组件以接受数字以及返回数字的函数 - 在
OrderProgress
的ngOnInit
中,按如下方式绑定:this.baseComponent.value = () => this.order.currentStage
但它也需要我更改Progress
组件。有没有一种方法不需要我更改Progress
或Order
?
听起来您需要在order对象上实现一个可观察的对象。如果您在多个组件之间共享该对象,并且需要让这些组件知道订单对象的更改,那么最好创建一个Observable。我们使用rxjs中的BehavoirSubject类来实现这一点。
RxJs行为主题
以下是如何创建BehavoirSubject:的示例
export class TokenService {
public tokenSubject: BehaviorSubject<OpenIdToken> = new BehaviorSubject<OpenIdToken>(<OpenIdToken>{});
OpenIdToken是一个自定义的typescript类,我想在我的应用程序中共享它。
以下是如何通知订阅者对底层对象的更改:
setObservableToken(token: OpenIdToken): void {
if (token) {
this.tokenSubject.next(token);
}
}
next被调用后,新的令牌对象值将向所有订阅者发布。以下是您订阅行为主题的方式:
export class PatientComponent implements OnInit, OnDestroy {
patient: Patient;
constructor(private _tokenService: TokenService, private _patientService: PatientService) { }
ngOnInit() {
this._tokenService.tokenSubject.subscribe(token => {
if (token && token.access_token && token.access_token.length>0) {
this._patientService.getPatient(token)
.subscribe(_patient => this.patient = _patient);
}
});
}
subscribe是一个委托,它将在订阅广播对令牌的更改时执行(当它调用.next(token)时)。在这种情况下,当我获得OpenIdToken时,我想使用该令牌获取患者,因此我调用另一个服务。
订单类型必须是Subject或BehaviorSubject,因此当您更新订单时,myprogress的模板也应该更新。您将需要使用异步管道来订阅observable。
<myprogress [order]="order$ | async"></myprogress>
检查此代码。您需要致电this.newOrder({...});
来更新订单。
@Component({
selector: 'page-home',
template: `
<ion-header>
<ion-navbar>
<ion-title>Home</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<myprogress [order]="order$ | async"></myprogress>
</ion-content>
`
})
export class HomePage implements OnInit,OnDestroy{
order$: Subject<any> = new Subject();
constructor(public navCtrl: NavController){
}
ngOnInit(){
}
newOrder(order : any){
this.order$.next(order);
}
ngOnDestroy(){
this.order$.unsubscribe();
}
}