我已经实现了 ControlValueAccessor,如我正在关注的教程中所示。但是,我实现 controlvalueaccessor 的组件似乎没有检测到 ngModel 的任何更改。我错过了什么?
import { Component, OnInit, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-counter',
templateUrl: './counter.component.html',
styleUrls: ['./counter.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CounterComponent),
multi: true
}
]
})
export class CounterComponent implements OnInit, ControlValueAccessor {
constructor() { }
counterValue = 0;
writeValue(value: any) {
console.log('writeValue: ', value);
}
registerOnChange(fn: any) {
console.log('on change: ', fn);
}
registerOnTouched(fn: any) {
console.log('on touch: ', fn);
}
increment() {
this.counterValue++;
}
decrement() {
this.counterValue--;
}
ngOnInit() {
}
}
Run Code Online (Sandbox Code Playgroud)
模板:
<button (click)="increment()">Increment</button>
{{ counterValue }}
<button (click)="decrement()">Decrement</button>
Run Code Online (Sandbox Code Playgroud)
和:
<app-counter name="counter" [(ngModel)]="counter"></app-counter>
<p>ngModel: {{ counter }}</p>
Run Code Online (Sandbox Code Playgroud)
在本教程的这一点上,递增/递减计数器应该会触发我定义的 controlvalueaccessor 方法,但事实并非如此。
您必须登记变更。做这样的事情:
import {Component, OnInit, forwardRef} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
@Component({
selector: 'app-counter',
template: `
<button (click)="increment()">Increment</button>
{{ counterValue }}
<button (click)="decrement()">Decrement</button>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CounterComponent),
multi: true
}
]
})
export class CounterComponent implements ControlValueAccessor {
constructor() { }
counterValue = 0;
writeValue(value: any) {
this.counterValue = value;
}
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
private onChangeCallback: (_: any) => void = () => {};
registerOnTouched(fn: any) {
console.log('on touch: ', fn);
}
increment() {
this.counterValue++;
this.onChangeCallback(this.counterValue);
}
decrement() {
this.counterValue--;
this.onChangeCallback(this.counterValue);
}
}
Run Code Online (Sandbox Code Playgroud)
或者使用 setter 的更优雅的版本:
import {Component, OnInit, forwardRef} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
@Component({
selector: 'app-counter',
template: `
<button (click)="increment()">Increment</button>
{{ counterValue }}
<button (click)="decrement()">Decrement</button>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CounterComponent),
multi: true
}
]
})
export class CounterComponent implements ControlValueAccessor {
private _counterValue = 0;
get counterValue(): number {
return this._counterValue;
}
set counterValue(value: number) {
this._counterValue = value;
this.onChangeCallback(value);
}
writeValue(value: any) {
this.counterValue = value;
}
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
private onChangeCallback: (_: any) => void = () => {};
registerOnTouched(fn: any) {
console.log('on touch: ', fn);
}
increment() {
this._counterValue++;
}
decrement() {
this._counterValue--;
}
}
Run Code Online (Sandbox Code Playgroud)
PS:不要忘记使用传入值更新内部模型,如writeValue()两个示例所示。
| 归档时间: |
|
| 查看次数: |
2739 次 |
| 最近记录: |