Angular 中的双向数据绑定

时间:2021-01-17 05:29:58

标签: angular ngmodel angular2-ngmodel

我的问题是指所有 Angular 版本 >= 2

所以对于双向数据绑定,Angular 是否支持使用 ngModel 开箱即用。是否仅支持表单控件,例如输入框?

开箱即用的支持是否不适用于自定义组件?例如我们不能像下面那样直接使用 ngModel 作为自定义组件吗?还是需要自定义代码?

<custom-counter [(ngModel)]="someValue"></custom-counter>

2 个答案:

答案 0 :(得分:3)

您可以在此stackblitz link

中找到演示

对于您的任何自定义组件,如果您需要使用 [(ngModel)],那么您需要使用您的自定义 ControlValueAccessor 基类。

创建一个名为 AbstractValueAccessor...

import { Component, forwardRef, HostBinding, Input } from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";    

const noop = () => {};
export abstract class AbstractValueAccessor implements ControlValueAccessor {
  //The internal data model
  private innerValue: any = "";

 //Placeholders for the callbacks which are later provided
 //by the Control Value Accessor

 private onTouchedCallback: () => void = noop;
 private onChangeCallback: (_: any) => void = noop;

 //get accessor
 get value(): any {
   return this.innerValue;
 }

 //set accessor including call the onchange callback
 set value(v: any) {
    if (v !== this.innerValue) {
    this.innerValue = v;
    this.onChangeCallback(v);
 }

}

//Set touched on blur
onBlur() {
  this.onTouchedCallback();
}

//From ControlValueAccessor interface
 writeValue(value: any) {
   if (value !== this.innerValue) {
      this.innerValue = value;
   }
 }

 //From ControlValueAccessor interface
  registerOnChange(fn: any) {
     this.onChangeCallback = fn;
  }

 //From ControlValueAccessor interface
  registerOnTouched(fn: any) {
     this.onTouchedCallback = fn;
  }
}

 export function MakeProvider(type: any) {
    return {
         provide: NG_VALUE_ACCESSOR,
         useExisting: forwardRef(() => type),
         multi: true
    };
 }

现在,您需要在自定义组件中使用上述类。

自定义组件

import { Component, OnInit } from "@angular/core";
import {
   AbstractValueAccessor,
   MakeProvider
} from "../app/abstract-value-accessor";

@Component({
  selector: "app-custom-input",
  templateUrl: "./custom-input.component.html",
  styleUrls: ["./custom-input.component.css"],
  providers: [MakeProvider(CustomInputComponent)]
})

export class CustomInputComponent extends AbstractValueAccessor
  implements OnInit {
   ngOnInit() {}
}

上面,providers: [MakeProvider(CustomInputComponent)] 这一行,我们为组件提供了自定义值访问器。现在,我们可以使用这个组件了。

app-component.html

<app-custom-input [(ngModel)]="customValue"></app-custom-input>

app-component.ts

 customValue = 'custom-value';

答案 1 :(得分:0)

Angular 提供了 ControlValueAccessor 来控制自定义组件。

ControlValueAccessor 接口提供了利用 Angular 表单 API 的能力,并在它和 DOM 元素之间创建连接。

以下是实现此概念的示例:

https://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel

相关问题