详解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 } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。