angular - Angular - 如何处理双重绑定和验证?
问题描述
当试图实现一个复杂的组件(日期和时间输入)时,这个问题就开始了,父组件拥有一个明确的“状态”(复合时间戳)。父组件使用一个子组件(一个数字字段),它采用双重绑定来更新状态的相关部分。
孩子不知道(也不应该)完整的验证逻辑,所以它会(通过一个Output
属性)发出它所有的值变化。其中一些值将导致无效状态(例如时间戳超过允许的最大值)。在这种情况下,我想停止事件的传播,并让父组件“重置”子组件的状态。
但是,这不会发生,因为(就更改检测而言)父级的状态没有改变,所以input
子级的属性没有重置。
我在Stackblitz 上将这个问题降到最低。
然而,问题的核心很简单:
@Component({
selector: "my-child",
template: `
Value on the child: {{ value }}<br />
<button (click)="value = value + 1">Increment</button>
`
})
export class ChildComponent {
private _value = 0;
get value() {
return this._value;
}
@Input() set value(v: number) {
if (v !== this._value) {
this._value = v;
this.valueChange.emit(v);
}
}
@Output() valueChange = new EventEmitter<number>();
}
@Component({
selector: "my-app",
template: `
<div>The value on the parent is: {{ parentValue }}</div>
<my-child [(value)]="parentValue"></my-child>
`
})
export class AppComponent {
_parentValue = 0;
get parentValue() {
return this._parentValue;
}
set parentValue(v: number) {
// discard values more than 5 because they are "invalid"
// probably I shouldn't just "return", but what to do?
if (this.isInvalid(v)) return;
this._parentValue = v;
}
isInvalid(v: number) {
return v > 5;
}
}
单击子项将使子项value
超过 5,而parentValue
将保持其最大值为 5。并且,由于parentValue
没有更改,因此更改检测不会在子组件中设置 input 属性。
让父母完全拥有状态并在适当时“重置”它的孩子的最佳方式应该是什么?我可以使用ViewChildren
并破解它,但实际情况显然要复杂得多,我正在寻找一个可以遵循的一般模式。
解决方案
推荐阅读
- mysql - MYSQL - 'NA'的全文匹配失败
- javascript - 如何在对话框中更改集合中的字符串的文本颜色
- git - 如何在不覆盖 PR 和更改作者的情况下修改历史提交消息?
- logstash - 为什么filebeat会尝试连接elasticseach?
- javascript - How to pass data for partial view using Jquery
- angular - 在 Eclipse 中创建 Angular 项目失败,并显示消息“目录 \drivers\etc 不存在”
- c# - Xamarin 从 listview+sqlite 数据库中删除
- r - 使用 Gelman-Rubin PSRF 进行收敛诊断:R coda package vs Runjags
- python - 如何使用字典将数据插入数据框,如果列中存在键则设置值
- .net - .netcore 2.2 从 iframe 调用页面时的会话变量问题