今天就跟大家聊聊有关angular4怎么通过自定义组件实现ngModel双向数据绑定,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
成都创新互联公司自2013年创立以来,先为镇沅等服务建站,镇沅等地企业,进行企业商务咨询服务。为镇沅企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。app-child组件:
import { Component, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css'], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ChildComponent), multi: true }] }) export class ChildComponent implements ControlValueAccessor { constructor() { } _data: any; add () { this.childData ++; } change = (value: any) => {}; // 先定义一个方法,很重要,用于接收registerOnChange()方法里传递回来的方法,然后通过这个方法就能通知到外部组件数据更新。 set childData(value: number) { // childData被更改走该方法 this._data = value; this.change(this._data); // 将更新后的数据通知到外部组件 } get childData() { // 页面或者方法里面有调用childData就会走该方法 return this._data; } writeValue(val): void { // 初始化时,获取并监听父组件通过ngModel传递进来的数据 if (val) { this._data = val; } } registerOnChange(fn: any): void { // 初始化后,执行该方法,并保存控件接收到 change 事件后,调用的函数 this.change = fn; } registerOnTouched(fn: any): void { } }
3、下面开始说下实现的过程吧:
如果添加ngModel后报如下错误,检查组件对应的Module文件有没有导入FormsModule
import { FormsModule } from '@angular/forms'; @NgModule({ ... imports: [ ..., FormsModule ], ... })
import FormsModule后,控制台任然会报错:
这是因为我们需要在使用ngModel的组件里实现ControlValueAccessor的接口方法。
先引入和使用我们必须使用的配置:
import { Component, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css'], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ChildComponent), // 这里的组件名为当前组件的名字 multi: true }] }) export class ChildComponent implements ControlValueAccessor { constructor() { } childData = 2; }
处理完成后控制台的报错信息已经改变:
这是因为ControlValueAccessor的接口有几个必须存在的方法,会自动去调用:
writeValue(val): void { } registerOnChange(fn: any): void { } registerOnTouched(fn: any): void { }
初始化的时候调用 writeValue()
方法,将会使用表单模型中对应的初始值作为参数(也就是ngModel里的值)。
registerOnChange() 可以用来通知外部,组件已经发生变化。
registerOnTouched() 方法用于设置当控件接收到 touched 事件后,调用的函数。
知道了这三个方法后,我们就可以在writeValue方法里给组件设置父组件通过ngModel传递过来的值了。如:
writeValue(val): void { if (val) { this.childData = val; } }
那么怎么将组件里更新的数据传递给父组件呐。
registerOnChange(fn: any): void { // 初始化后,执行该方法,并保存控件接收到 change 事件后,调用的函数 this.change = fn; }
writeValue()方法后就会执行registerOnChange()方法,我们就是通过该方法传递回来的方法参数来通知到外部组件数据更新的,所以我们要在最开始就定义一个方法来接收。
change = (value: any) => {}; // 先定义一个方法,很重要,用于接收registerOnChange()方法里传递回来的方法,然后通过这个方法就能通知到外部组件数据更新。
然后就可以通过change方法通知外部组件了
set childData(value: number) { // childData被更改走该方法 this._data = value; this.change(this._data); // 将更新后的数据通知到外部组件 }
最开始贴出来的代码,中间使用了set 和get去处理了数据,在get childData()方法里打断点发现会执行很多次该方法,其实也可以修改成通过更新数据的时候就直接调用change()方法来通知外部组件数据更新,如下:
import { Component, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css'], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ChildComponent), multi: true }] }) export class ChildComponent implements ControlValueAccessor { constructor() { } _data: any; childData = 1; add () { this.childData ++; this.change(this.childData); } change = (value: any) => {}; // 先定义一个方法,很重要,用于接收registerOnChange()方法里传递回来的方法,然后通过这个方法就能通知到外部组件数据更新。 writeValue(val): void { // 初始化时,获取并监听父组件通过ngModel传递进来的数据 if (val) { this.childData = val; } } registerOnChange(fn: any): void { // 初始化后,执行该方法,并保存控件接收到 change 事件后,调用的函数 this.change = fn; } registerOnTouched(fn: any): void { } }
看完上述内容,你们对angular4怎么通过自定义组件实现ngModel双向数据绑定有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注创新互联行业资讯频道,感谢大家的支持。