2017-01-19 56 views
3

我有一個公開的幾個可綁定屬性,並可以這樣用我的根頁上的組件:Angular2/Ionic2 ::刷新組件

<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函數只運行一次,並且無法向指令指示訂單的某些屬性已更改,並且需要計算valuemax的新值。

有沒有辦法解決這個問題?

一個可能的解決方案,我有是這樣的:

  1. 修改Progress組件接受的數字,以及一個返回數的函數。
  2. OrderProgressngOnInit,綁定如下:this.baseComponent.value =() => this.order.currentStage

但是,它需要我改變Progress組成部分,也是。有沒有一種方法不需要我改變ProgressOrder

+0

如果我明白你的理解,我會用''Subject''來看答案。您希望父組件順序中的更改反映在子指令中。在父指令中,當訂單的價值突變時,不會更改子訂單中訂單的檢測更改值? – raj

+0

對不起,我沒有完全理解你提出的問題。你能稍微改述一下你的問題嗎? – AweSIM

回答

1

這聽起來像你需要在訂單對象上實現observable。如果您要跨多個組件共享該對象,並且需要讓這些組件知道訂單對象的更改,最好創建一個Observable。我們使用rxjs的BehavoirSubject類來做到這一點。

RxJs BehaviorSubject

這裏是和示例如何,您可以創建BehavoirSubject:

export class TokenService { 

    public tokenSubject: BehaviorSubject<OpenIdToken> = new BehaviorSubject<OpenIdToken>(<OpenIdToken>{}); 

OpenIdToken是,我想在我的應用程序共享一個自定義的打字稿類。

這裏是你如何notifiy更改基礎對象的用戶:

setObservableToken(token: OpenIdToken): void { 
     if (token) { 
      this.tokenSubject.next(token); 
     } 
    } 

。接下來被稱爲後的新標記對象的值將propigate給所有用戶。這裏是你如何訂閱BehaviorSubject:

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); 
      } 
     }); 
    } 

認購時的認購廣播變化令牌(當它。接下來調用(令牌))將執行的委託。在這種情況下,當我得到一個OpenIdToken時,我想使用令牌獲取病人,所以我打電話給另一個服務。

+0

和@victor都給出了技術上正確的解決方案。我同意這可以用observables更好地完成。你的答案,恕我直言,是更好的,因爲你定義模型類本身內的觀察。在另一個答案中,observable在頁面級定義。當其他頁面也改變'訂單'模型時,該解決方案不能很好地擴展。所以我會將你的答案標記爲正確答案。 – AweSIM

1

訂單類型必須是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(); 
    } 

}