我有一个 Angular 应用程序,其中包含一个允许用户增加数量的表单。
这是上面示例中的父组件:
@Component({
selector: 'app-root',
standalone: true,
imports: [Counter],
template: `<h1>Counter</h1>
<Counter [value]="1" [control]="qtyForm"></Counter>
<p>Value from form emission:</p>
<p>{{newQuantity}}</p>`,
})
export class App {
newQuantity!: number | null;
qtyForm = new FormControl(0, [Validators.required, Validators.max(99)]);
ngAfterViewInit() {
this.updateCustomQuantity();
}
updateCustomQuantity() {
this.qtyForm.valueChanges
.subscribe((qty) => {
this.newQuantity = qty;
});
}
}
和子(计数器)组件:
@Component({
selector: 'Counter',
standalone: true,
imports: [MatFormFieldModule, MatInputModule, ReactiveFormsModule],
template: `
<p>Need to increment/decrement twice before form emits:</p>
<button (click)="decrement()">Subtract</button>
<mat-form-field>
<input matInput [formControl]="control">
</mat-form-field>
<button (click)="increment()">Add</button>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Counter),
multi: true,
},
],
encapsulation: ViewEncapsulation.None,
})
export class Counter implements ControlValueAccessor, OnInit {
formControlDirective!: FormControlDirective;
currentValue!: number | null | undefined;
@Input() value!: number;
@Input() control!: FormControl;
ngOnInit() {
this.control.patchValue(this.value, { emitEvent: false });
this.currentValue = this.value;
}
increment() {
const currentValue = this.control.value;
this.control.patchValue(currentValue + 1);
}
decrement() {
const currentValue = this.control.value;
this.control.patchValue(currentValue - 1);
}
...
}
我不得不承认我对此有点困惑。从 ngOninit() 中删除 emitEvent: false 没有任何效果。
解决方法是将
ngAfterViewInit
更改为 ngOnInit
并且工作正常,至于为什么 ngAfterViewInit
没有在加载时触发对我来说是个谜,也许其他人可以解释这一点,或者你可以提出Angular github 页面中的票证!
import { Component, AfterViewInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FormControl, Validators } from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { Counter } from '../Counter';
@Component({
selector: 'app-root',
standalone: true,
imports: [Counter, CommonModule, ReactiveFormsModule, FormsModule],
template: `<h1>Counter</h1>
<Counter [value]="0" [control]="qtyForm"></Counter>
<p>Value from form emission:</p>
<p>{{newQuantity}}</p>`,
})
export class App {
newQuantity!: number | null;
qtyForm = new FormControl(1, [Validators.required, Validators.max(99)]);
ngOnInit() {
console.log('asdf');
this.updateCustomQuantity();
}
updateCustomQuantity() {
console.log(this.qtyForm.value);
this.newQuantity = this.qtyForm.value;
this.qtyForm.valueChanges.subscribe((qty) => {
this.newQuantity = qty;
});
}
}
bootstrapApplication(App);