HostBinding to value 仅在第一次有效
HostBinding to value works only the first time
我有一个执行值格式化的 ControlValueAccessor 指令,但它的 @HostBinding('value')
只在第一次工作。
@Component({
selector: 'my-app',
template: `
Value: {{value}}<br/>
<input type="text" uppercase [(ngModel)]="value">
<button type="button" (click)="reset()">Reset</button>
`,
})
export class AppComponent {
value = 'Angular ' + VERSION.major;
reset() {
this.value = 'Reset';
}
}
@Directive({
selector: 'input[uppercase]',
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => UpperCaseInputDirective), multi: true }],
})
export class UpperCaseInputDirective implements ControlValueAccessor {
@HostBinding('value') lowerValue = '';
...
}
请在 https://stackblitz.com/edit/angular-ivy-vfahu3?file=src%2Fapp%2Fapp.component.ts
查看完整示例
- 当我第一次点击“重置”按钮时,会按预期将 ngModel 设置为“重置”,并将
<input>
的文本设置为“重置”。
- 然后我将输入值编辑为“测试”,该值按预期作为“测试”传播回模型。
- 当我第二次单击“重置”按钮时,ngModel 按预期设置为“重置”,但
<input>
的文本仍保留为“测试”。我希望它像在第 1 点中那样更改为“重置”。
你能解释一下这种行为吗?有什么线索吗?
旁注: 我知道上面的示例可以通过其他方式实现,但这只是我使用 <input type="datetime-local>
并且指令翻译的情况的简化ISO 格式的输入值。
我意识到由于 Angular 优化,该值未更新 - 如果它认为该值没有改变,它不会将值传播到 DOM。在第 1 点,它将绑定变量更改为值“Reset”,在第 3 点,它“认为”该值仍然是“Reset”,因此它不会更新 DOM.
当我在 onChange
侦听器(第 2 点)中更新绑定变量 this.lowerValue
时,重置按钮在第 3 点起作用:
@HostListener('change', ['$event']) onChange(event: Event) {
if (event.target instanceof HTMLInputElement) {
this.lowerValue = event.target.value?.toLocaleUpperCase();
}
this._onChangeCallback(this.lowerValue);
}
我有一个执行值格式化的 ControlValueAccessor 指令,但它的 @HostBinding('value')
只在第一次工作。
@Component({
selector: 'my-app',
template: `
Value: {{value}}<br/>
<input type="text" uppercase [(ngModel)]="value">
<button type="button" (click)="reset()">Reset</button>
`,
})
export class AppComponent {
value = 'Angular ' + VERSION.major;
reset() {
this.value = 'Reset';
}
}
@Directive({
selector: 'input[uppercase]',
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => UpperCaseInputDirective), multi: true }],
})
export class UpperCaseInputDirective implements ControlValueAccessor {
@HostBinding('value') lowerValue = '';
...
}
请在 https://stackblitz.com/edit/angular-ivy-vfahu3?file=src%2Fapp%2Fapp.component.ts
查看完整示例- 当我第一次点击“重置”按钮时,会按预期将 ngModel 设置为“重置”,并将
<input>
的文本设置为“重置”。 - 然后我将输入值编辑为“测试”,该值按预期作为“测试”传播回模型。
- 当我第二次单击“重置”按钮时,ngModel 按预期设置为“重置”,但
<input>
的文本仍保留为“测试”。我希望它像在第 1 点中那样更改为“重置”。
你能解释一下这种行为吗?有什么线索吗?
旁注: 我知道上面的示例可以通过其他方式实现,但这只是我使用 <input type="datetime-local>
并且指令翻译的情况的简化ISO 格式的输入值。
我意识到由于 Angular 优化,该值未更新 - 如果它认为该值没有改变,它不会将值传播到 DOM。在第 1 点,它将绑定变量更改为值“Reset”,在第 3 点,它“认为”该值仍然是“Reset”,因此它不会更新 DOM.
当我在 onChange
侦听器(第 2 点)中更新绑定变量 this.lowerValue
时,重置按钮在第 3 点起作用:
@HostListener('change', ['$event']) onChange(event: Event) {
if (event.target instanceof HTMLInputElement) {
this.lowerValue = event.target.value?.toLocaleUpperCase();
}
this._onChangeCallback(this.lowerValue);
}