javascript - Rätt sätt att sprida beräknat värde i Angular2
Jag vill använda beräknat värde via @Input-egenskaper
Men att sprida initialt värde fungerar inte bra.
https://plnkr.co/edit/1MMpOYOKIouwnNc3uIuy
Jag skapar App (rotkomponent med formulär styrt av mall) och NumComponent (barnkomponent som bara sparar inmatat värde) komponent.
När jag skickar en attribut till NumComponent som [useThree]="true" vill jag sedan sätta standardvärdet '3' till NumComponent
Men jag kan inte hitta ett sätt utan att använda setTimeout
Finns det ett sätt att sprida initialvärdet utan setTimeout?
Redigerad den 5/5
App-komponent
@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 {}
NumComponent
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 {}
}
Det verkar som att föräldrakomponenten inte inser det propagade värdet vid initialiseringslivscykeltiden.
Svar #1
Jag är inte säker på att jag har förstått problemet fullt ut, men en möjlig lösning på det du letar efter skulle kunna vara
private _useThree = false;
@Input() set useThree(value: boolean) {
this._useThree = value;
if (this._useThree) {
this.num = 3;
}
}
På så sätt, när du vill sätta värdet på input-egenskapen useThree från föräldrakomponenten, kör du faktiskt koden i setter-metoden som definierats ovan.
