【发布时间】:2017-05-04 16:20:48
【问题描述】:
我想使用 @Input 属性的计算值
但传播初始值效果不佳。
https://plnkr.co/edit/1MMpOYOKIouwnNc3uIuy
我创建了App(具有模板驱动表单的根组件)和NumComponent(仅保存类型值的子组件)组件。
当我像[useThree]="true" 一样将属性传递给NumComponent 时,我想将默认值'3' 设置为NumComponent
但我找不到不使用setTimeout的方法
有没有办法在没有 setTimeout 的情况下传播初始值?
于 5 月 5 日编辑
应用组件
@Component({
selector: 'my-app',
template: `
<div>
<form novalidate #form="ngForm">
<app-num name="num" ngModel [useThree]="true"></app-num>
</form>
<pre>{{form.value | json}}</pre>
</div>
`
})
export class App {}
数字组件
export const NumValueAccessor = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NumComponent),
multi: true
};
@Component({
selector: 'app-num',
template: `<input [(ngModel)]="num" type="text" (ngModelChange)="updateValue()" />`,
providers: [NumValueAccessor]
})
export class NumComponent implements ControlValueAccessor {
num = 0;
// I want set literal number 3 to `num` property
// when `useThree` is true.
@Input() useThree = false;
onChange = (_: any) => {};
updateValue(num = this.num) {
this.onChange(String(num));
}
writeValue(value: string): void {
if (this.useThree) {
/**********
* ISSUE
**********/
// this code is not work. after code ran, `NumComponent` has
// value 3 but AppComponent's internal FormComponent value
// is '' (empty string)
// this.num = 3;
// this.updateValue(3);
// ran code with `setTimeout` solve this problem. but
// I don't want using setTimeout for this feature.
// setTimeout(() => {
// this.num = 3;
// this.updateValue(3);
// }, 0);
// Is there any way to propagate computed initial value?
this.num = 3;
this.updateValue(3);
/**********
* ISSUE
**********/
this.useThree = false;
return;
}
this.num = Number(value);
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {}
setDisabledState(isDisabled: boolean): void {}
}
似乎父组件在初始化生命周期时没有实现传播值。
【问题讨论】:
-
请在minimal reproducible example中提供所有相关代码在问题本身中,不仅在第三方网站上。
-
@MikeMcCaughan 我用 cmets 添加了相关代码。我为需要执行演示的人维护以前的 plunker 链接。 :)
-
模板驱动的表单是异步的。
registerOnChange函数在您在writeValue中调用this.updateValue后执行。NgModel不会同步添加表单控件 — 它是在微任务中添加的 (promise.then)。您只能通过像这样plnkr.co/edit/A4xBldIIj58fPFjzndEW?p=preview 安排另一个微任务来等待 -
@yurzui 非常感谢 :)
标签: javascript angular typescript