Reputation: 372
How to display some text in input FormControl that not equal to value of this FormControl?
For example, get some object from a server - {id: 1, name: "Name1"}
, and set value
of FormControl to that object or to object.id but display value
set to object.name - "Name1".
Why i need it:
I use angular material autocomplete and it set the value of FormControl to object (from selected mat-option) and display value to string via displayWith. I want to repeate this behavior when fetch data from server for some consistency and convenience
Upvotes: 10
Views: 12922
Reputation: 316
I've subscribed to the formControl valueChanges
observable and validate the value with a condition, and reset it if it needs to:
this.myForm.valueChanges.subscribe( value => {
if(this.validateFormValue(value)){
this.myForm.patchValue(this.extractValue(value))
}
})
validateFormValue(value){
// if condition
return true
// else return false
}
extractValue(value){
// return the value you want after calculation or extraction
return value.realValue
}
Upvotes: 0
Reputation: 57939
Another aproach is use [ngModel] and (ngModelChange) inside the FormGroup. Remember that the formControl exist always. The idea is simple. Imagine you has a FormGroup
form=new FormGroup({
control:new FormControl()
})
<form [formGroup]="form">
<input [ngModel]="form.get('control').value?form.get('control').value.name:''"
(ngModelChange)="form.get('control').setValue({id:$event})"
[ngModelOptions]="{standalone:true}">
</form>
But if you're using mat-autocomplete, by defect is asigned to the formControl the object and you can also "initialize" the formControl :(. Is the second example in the docs
Upvotes: 0
Reputation: 457
You can also just use the setValue()
twice.
First set the control value to the value that you want to display (view). Then set the control value again with the value that you want to save (model), but this time without changing the view, by using {emitModelToViewChange: false}
this.form?.controls.country.setValue('Value to display')
this.form?.controls.country.setValue('realValue', {emitModelToViewChange: false});
Upvotes: 3
Reputation: 372
I do some research for my question.
It is need to use FormControlDirective and its valueAccessor.writeValue()
for set display value of input (it use renderer) or as alternative nativeElement.value
.
And FormControl's setValue()
with emitModelToViewChange = false
for set FormControl value.
In template
<input [formControl]="ctrlF" #ctrlD="ngForm">
In controller
@ViewChild('ctrlD', {read: FormControlDirective})
ctrlD :FormControlDirective
...
this.ctrlD.valueAccessor.writeValue("display value")
this.ctrlD.control.setValue({foo: "foo", bar: "bar"}, {
emitModelToViewChange: false
})
Upvotes: 7