详解Angular中实现自定义组件的双向绑定的两种方法
在Angular中,对于表单元素,通过[(ngModel)]即可以简单地实现双向绑定。对于自定义组件而言,希望实现同样的效果可以怎么做呢?
1实现自定义组件的ngModel指令
如果希望自定义组件能够具有与表单元素相同的ngModel效果,可以通过在组件内实现ControlValueAccessor接口达到目的。
对于[(ngModel)],需要至少实现该接口的如下方法:
interfaceControlValueAccessor{
writeValue(obj:any):void
registerOnChange(fn:any):void
registerOnTouched(fn:any):void
}
最简单的核心实现示例参考如下。
import{ControlValueAccessor}from'@angular/forms/src/directives';
import{Component,forwardRef,Input}from'@angular/core';
import{NG_VALUE_ACCESSOR}from'@angular/forms';
@Component({
selector:'custom-input',
template:``,
providers:[
{
provide:NG_VALUE_ACCESSOR,
useExisting:forwardRef(()=>UnionInputComponent),
multi:true
}
]
})
exportclassCustomInputComponentimplementsControlValueAccessor{
constructor(){}
privateinnerValue:any='';
privateonTouchedCallback:()=>void=function(){};
privateonChangeCallback:(_:any)=>void=function(){};
getvalue():any{
returnthis.innerValue;
}
setvalue(v:any){
if(v!==this.innerValue){
this.innerValue=v;
this.onChangeCallback(v);
}
}
/**
*modelview->viewvalue
*/
writeValue(value:any){
if(value!==this.innerValue){
this.innerValue=value;
}
}
/**
*viewvalue->modelvalue
*/
registerOnChange(fn:any){
this.onChangeCallback=fn;
}
registerOnTouched(fn:any){
this.onTouchedCallback=fn;
}
}
2使用get/set关键字实现父子组件的双向绑定
其实实现双向绑定内部的本质原理就是父子组件的事件绑定机制。简单举例如下。
2.1自定义子组件定义
import{Input,Output,Component,EventEmitter}from'@angular/core';
@Component({
selector:'custom-input',
template:``,
})
exportclassCustomInputComponent{
innerValue;
@Input()
gettwoWayModel(){
returnthis.innerValue;
}
settwoWayModel(val){
this.innerValue=val;
this.twoWayModelChange.emit(this.innerValue);
}
@Output()twoWayModelChange:EventEmitter=newEventEmitter ();
}
2.2使用自定义组件
在需要使用组件的地方,通过[(twoWayModel)]即可实现双向绑定的效果。
import{Input,Output}from'@angular/core';
import{Component,forwardRef,Input}from'@angular/core';
@Component({
selector:'custom-input',
template:``
})
exportclassabcComponent{
inputValue;
onInputValueChange(val){
console.log(val);
console.log(val===this.inputValue);//true
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。