欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解Angular中实现自定义组件的双向绑定的两种方法

程序员文章站 2022-11-09 16:08:27
在 angular 中,对于表单元素,通过 [(ngmodel)] 即可以简单地实现双向绑定。对于自定义组件而言,希望实现同样的效果可以怎么做呢? 1 实现自定义组件的...

在 angular 中,对于表单元素,通过 [(ngmodel)] 即可以简单地实现双向绑定。对于自定义组件而言,希望实现同样的效果可以怎么做呢?

1 实现自定义组件的 ngmodel 指令

如果希望自定义组件能够具有与表单元素相同的 ngmodel 效果,可以通过在组件内实现 controlvalueaccessor 接口达到目的。

对于 [(ngmodel)] ,需要至少实现该接口的如下方法:

interface controlvalueaccessor { 
 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: `<input [(ngmodel)]="value"/>`,
 providers: [
  {
   provide: ng_value_accessor,
   useexisting: forwardref(() => unioninputcomponent),
   multi: true
  }
 ]
})
export class custominputcomponent implements controlvalueaccessor {
 constructor() { }
 private innervalue: any = '';
 private ontouchedcallback: () => void = function () { };
 private onchangecallback: (_: any) => void = function () { };

 get value(): any {
  return this.innervalue;
 }
 set value(v: any) {
  if (v !== this.innervalue) {
   this.innervalue = v;
   this.onchangecallback(v);
  }
 }
 /**
  * model view -> view value
  */
 writevalue(value: any) {
  if (value !== this.innervalue) {
   this.innervalue = value;
  }
 }
 /**
  * view value ->model value
  */
 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: `<input [(ngmodel)]="innervalue"/>`,
})
export class custominputcomponent {
 innervalue;

 @input()
 get twowaymodel() {
  return this.innervalue;
 }
 set twowaymodel(val) {
  this.innervalue = val;
  this.twowaymodelchange.emit(this.innervalue);
 }
 @output() twowaymodelchange: eventemitter<string> = new eventemitter</string><string>();
}

2.2 使用自定义组件

在需要使用组件的地方,通过 [(twowaymodel)] 即可实现双向绑定的效果。

import { input, output } from '@angular/core';
import { component, forwardref, input } from '@angular/core';
@component({
 selector: 'custom-input',
 template: `<custom -input [(twowaymodel)]="inputvalue" (twowaymodelchange)="oninputvaluechange($event)"></custom>`
})
export class abccomponent {
 inputvalue;
 oninputvaluechange(val) {
  console.log(val);
  console.log(val === this.inputvalue); // true
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。