简体   繁体   English

Angular中的双向数据绑定

[英]Two-way data binding in Angular

My question is referring to all Angular versions >= 2我的问题是指所有 Angular 版本 >= 2

So for two-way data binding, does Angular support it out of the box using ngModel.因此,对于双向数据绑定,Angular 是否支持使用 ngModel 开箱即用。 Is it only supported for form controls eg input box?是否仅支持表单控件,例如输入框?

Is the out of box support not available for custom components?开箱即用的支持是否不适用于自定义组件? eg can we not use ngModel directly as below for a custom component?例如,我们不能像下面那样直接使用 ngModel 作为自定义组件吗? Or would that need custom code?还是需要自定义代码?

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

You can find demo here in this stackblitz link您可以在此stackblitz 链接中找到演示

For your any custom-component if you need to use [(ngModel)] then you need to use your custom ControlValueAccessor base class.对于您的任何自定义组件,如果您需要使用[(ngModel)] ,那么您需要使用您的自定义ControlValueAccessor基础 class。

Create one class called AbstractValueAccessor ...创建一个名为AbstractValueAccessor的 class ...

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
    };
 }

Now, You need to use above class in you custom-component.现在,您需要在自定义组件中使用上述 class 。

custom-component自定义组件

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() {}
}

above, providers: [MakeProvider(CustomInputComponent)] this line we provide our custom value accessor to our component.上面, providers: [MakeProvider(CustomInputComponent)]这一行我们为我们的组件提供了我们的自定义值访问器。 Now, we are ready to use this componen.现在,我们已经准备好使用这个组件了。

app-component.html应用组件.html

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

app-component.ts应用组件.ts

 customValue = 'custom-value';

Angular provides ControlValueAccessor to have control over custom components. Angular 提供ControlValueAccessor来控制自定义组件。

ControlValueAccessor interface gives the power to leverage the Angular forms API, and create a connection between it and the DOM element. ControlValueAccessor 接口提供了利用 Angular forms API 的能力,并在它和 DOM 元素之间创建连接。

Here is the example that implements this concept:这是实现此概念的示例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM