第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

angular4自定義組件非input元素實(shí)現(xiàn)ngModel雙向數(shù)據(jù)綁定

標(biāo)簽:
AngularJS

在angular里我们一般都是给input元素添加[(ngModel)]="value"实现数据双向绑定,如果想实现自定义的组件上实现ngModel双向数据绑定应该怎么办呐。。。

网上找了一下,没看懂记录一下。

场景:组件能获取父组件通过ngModel绑定的值,能通过ngModel改变父组件对应的数据。如下代码: 

<app-child [(ngModel])="appData"></app-child>

 

1、先贴出效果图:

 

2、下面是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 {
  }
}

复制代码

  中间不用使用get和set,不知道两种方法哪种更好。

 

  其实通过子组件通知父级组件数据更新,可以使用@Input和@Output来实现的,如果是@Input获取的父级组件的数据,父级组件数据更新,子组件需要在ngOnChanges生命周期里去监听对应的数据变更并处理相应的逻辑。

  不过在自定义组件上使用ngModel实现数据的双向绑定还可以用作表单处理上,比如表单模板和表单验证。

原文出处:https://www.cnblogs.com/amor17/p/10185015.html  

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺(jué)得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫(xiě)下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶(hù)
支付方式
打開(kāi)微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專(zhuān)欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消