Simplification : I have a calculator which won't allow "7" to be the result ( valid
will be false
).
The calculator itself is component which implements ControlValueAccessor
.
The model is
interface IModel {
a, b, c: number | null;
}
( a
is the left digit , b
is the middle one , and c
is the result)
This is how I wrote the template :
<input type='text' [ngModel]='myModel.a' (ngModelChange)='calc("a",$event)'/> +
<input type='text' [ngModel]='myModel.b' (ngModelChange)='calc("b",$event)'/> =
<input type='text' readonly [ngModel]='myModel.c' />
I didn't use banana in a box becuase I had to do a logic on each modification of the inputs.
I didn't use getter/setter either becuase otherwise- in the setter - I'd would have problem with controlling updates.
So that's why I use (ngModelChange)
. Where on each change I call the calc
function :
calc(propName,e) {
this.myModel[propName] = e;
this.myModel.c = +this.myModel.a + +this.myModel.b;
this.onChangeCallback(this.myModel);
}
But now things get complicated.
When changing the first input , I must tell the calc
function :
calc("a",$event)
and "b" in calc("b",$event)
. But this correlation seems WRONG to me :
Sure - I could add template variable to each and send that variable and to read .value
in the calc function.
But I think I'm going into the non-angular way
Question
How can I reference the model of the control when updating the input? ( Along with doing custom logic when set)
PS - I don't have the (input)
event since i'm using Angular in Nativescript.
You can use banana in a box
and your custom logic together.
Check this stackblitz
You can use [(ngModel)]
and (ngModelChange)="calc($event)"
together. What this will do is to update your model first and then call your custom function.
So, change your markup as follows
<input type='text' [(ngModel)]='myModel.a' (ngModelChange)='calc()'/> +
<input type='text' [(ngModel)]='myModel.b' (ngModelChange)='calc()'/> =
<input type='text' readonly [ngModel]='myModel.c'/>
calc
method:
calc() {
this.myModel.c = this.myModel.a * 1 + this.myModel.b * 1
}
Note: * 1
is for parsing string to number. It's a hack I'd like to use.
You can use Reactive from like this , Not much in template file ie html , all dirty stuff handle by Typescript
<form class="form-horizontal" [formGroup]="calculationForm" novalidate >
<input type='text' "formControlName"='a' /> +
<input type='text' "formControlName"='b'/> =
<input type='text' "formControlName"='c' />
</form>
Ts file would be
createForm() {
this.calculationForm= this.fb.group({
a: '',
b: '',
c: ''
});
}
get a() {
return this.calculationForm.get('a');
}
get b() {
return this.calculationForm.get('b');
}
get c() {
return this.calculationForm.get('c');
}
private onChanges(): void {
this.a.valueChanges.subscribe(() => this.calculate());
this.b.valueChanges.subscribe(() => this.calculate());
}
private calculate() {
if (this.a.value && this.b.value) {
this.c.setValue(this.a.value + this.b.value , {emitEvent: false});
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.