angular - Angular 中的双向数据绑定(bind)

标签 angular ngmodel angular2-ngmodel

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

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

开箱即用的支持是否不适用于自定义组件?例如我们可以不直接使用 ngModel 来创建自定义组件吗?或者需要自定义代码吗?

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

最佳答案

您可以在 stackblitz 中找到演示链接

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

创建一个名为 AbstractValueAccessor 的类...

import { forwardRef } 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';

关于angular - Angular 中的双向数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65757642/

相关文章:

javascript - 为什么当我的变量从可观察到的值每秒接收到一个新值时,ngModal不会更新输入值

Angular2 upgradeComponent 如何进行双向绑定(bind)

Angular 4 将数据/参数传递给模态(使用 ngfor)

Angular 设置颜色取决于 true 或 false

Angular - 具有多重绑定(bind)的 TextArea

html - 如何在选择下拉列表中应用占位符以及 Angular 6 中的 [ngmodel]?

html - 设置默认选择列表值 Angular2

angular - 在 Angular 的 INPUT 元素上使用 ngModel 中的管道

angular - 检查错误 'mat-expanded: true' 后 MatExpansionPanel 表达式已更改

javascript - 在 Angular 2 的 *ng-for 循环中添加 html