formControl 的監聽與廣播, 及setValue 選項

原文出處:https://www.cnblogs.com/keatkeat/p/5821974.html (Angular表單學習日誌,內容豐富,本文只截取一個點)

更新 : 2017-10-18 

formControl 的監聽與廣播 

兩種監聽方式 

1. control.valueChanges.subscribe(v)  

2. control.registerOnChange((value, emitViewToModelChange)

通常我們是想監聽來自 view 的更新, 當 accessor.publishMethod(v) 的時候, 上面第一種會被廣播, 第二種則收不到. 所以想監聽 view -> model 使用第一種 

那麼如果我們要監聽來自 control.setValue 的話, model -> view or just model change, 我們使用第 2 種, 

setValue 的options參數允許我們廣播時聲明要不要 讓第一種和第二種觸發

emitEvent = false 第一種不觸發

emitModelToViewChange = false 第 2 種不觸發 

emitViewToModelChange = false 第 2 種觸發, 然後第二個參數是 就是 emitViewToModelChange 

對了,雖然兩種叫 changes 但是值一樣也是會觸發的,如果不想重複值觸發的話,自己寫過濾唄.

總結: 

在做 view accessor 時, 我們監聽 formControl model to view 所以使用 registerOnChange

// view accessor 
this.viewValue = this.formControl.value; // first time
this.formControl.registerOnChange((v, isViewToModel) => { // model to view
  console.log('should be false', isViewToModel);
  this.viewValue = v;
});

然後通過 formControl view to model 更新

viewToModel(value: any) {
  this.formControl.setValue(value, {
    emitEvent: true,
    emitModelToViewChange: false,
    emitViewToModelChange: true
  });
}

 

 

然後呢在外部,我們使用 valueChanges 監聽 view to model 的變化

this.formControl.valueChanges.subscribe(v => console.log('view to model', v)); // view to model

再然後呢, 使用 setValue model to view 

modelToView(value: any) {
  this.formControl.setValue(value, {
    emitEvent: false,
    emitModelToViewChange: true,
    emitViewToModelChange: false
  });
}

 

 最關鍵的是在做 view accessor 時, 不要依賴 valueChanges 應該只使用 registerOnChange, 這好比你實現 angular ControlvalueAccessor 的時候,我們只依賴 writeValue 去修改 view.

對於 model to view 的時候是否允許 emitEvent 完全可以看你自己有沒有對其依賴,但 view accessor 肯定是不依賴的,所以即使 emitEvent false, model to view 依然把 view 處理的很好纔對。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章