十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
今天就跟大家聊聊有关angular4怎么通过自定义组件实现ngModel双向数据绑定,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
创新互联拥有10多年成都网站建设工作经验,为各大企业提供网站设计制作、做网站服务,对于网页设计、PC网站建设(电脑版网站建设)、重庆APP软件开发、wap网站建设(手机版网站建设)、程序开发、网站优化(SEO优化)、微网站、申请域名等,凭借多年来在互联网的打拼,我们在互联网网站建设行业积累了很多网站制作、网站设计、网络营销经验,集策划、开发、设计、营销、管理等网站化运作于一体,具备承接各种规模类型的网站建设项目的能力。
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双向数据绑定有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注创新互联行业资讯频道,感谢大家的支持。