原文出处: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 处理的很好才对。