Reputation: 4818
I have an Angular 7 reactive form which have, among others, the following fields:
<div class="ui-grid-col-2">
<select formControlName="network_interface" (change)="onInterfaceChange($event.target.value)">
<option *ngFor="let ifc of interfaces; let idx = index;" [value]="ifc.id">
{{ ifc.id }} - {{ ifc.name }}
</option>
</select>
</div>
<div class="ui-grid-col-2">
<select formControlName="interface_ip">
<option *ngFor="let obj of interfacesIps; let idx = index;" [value]="obj.id">
{{ obj.name }} ({{obj.address}})
</option>
</select>
</div>
Basically, it allows the user to select an interface and interface IP from 2 lists, stored in the arrays interfaces
and interfacesIps
.
One combo is 'tied' to the other, so if I select an interface the other combo must show its internal IP addresses. This is done in the onInterfaceChange
event handler, fired by the change
event. This is what I do:
onInterfaceChange(interfaceId : any): void {
// NOTE: this.interfaces[INDEX].ips is an array of IP addresses
this.interfacesIps = this.interfaces[interfaceId].ips;
}
This works, and the IP list is refreshed whenever I change the selected interface, BUT I've realized that the form control associated to the combo (interface_ip
) is not updated. It should be the first IP in the list, but I keeps the old value, until I change to another IP.
I've fixed this by manually changing the form control value on the event handler above, but I'd like to know if there's a way to do it automatically.
Thanks in advance,
Upvotes: 2
Views: 167
Reputation: 4818
Thanks for the suggestions! This is what I've done:
I've changed the [value]
for [ngValue]
. Now, the change
event on the dropdown isn't fired anymore, so I used the valueChanges
observable on the network interfaces form control to load the appropriate addresses when it changes:
this.formModel.controls['network_interface'].valueChanges((value) => {
// Update the addresses on interface change
this.interfacesIps = this.interfaces[value].ips;
});
Now all works as expected.
Thanks everyone!
Upvotes: 0
Reputation: 564
So if you need a dependend dropdown, you just need to populate the first with the data as you already did, to populate the second you need to use a propriety of reactive form called valueChanges, it's listen for changes of that formControl.
this.network_interface.valueChanges.subscribe((selectedValue) => {
/*
Here you select wich data to put in other select based on selectedValue
*/
});
Upvotes: 1
Reputation: 804
I think you need to change [value]
to [ngValue]
inside option tag.
Select tag doesn't have any value but option tag does have.so if you want to bind option's value in select tag, you need to use angular's SelectControlValueAccessor
which basically bind the option's value to select tag.
You can use SelectControlValueAccessor
by using ngValue
inside option tag.
You need to change your code as following:
<div class="ui-grid-col-2">
<select formControlName="network_interface" (change)="onInterfaceChange($event.target.value)">
<option *ngFor="let ifc of interfaces; let idx = index;" [ngValue]="ifc.id">
{{ ifc.id }} - {{ ifc.name }}
</option>
</select>
</div>
<div class="ui-grid-col-2">
<select formControlName="interface_ip">
<option *ngFor="let obj of interfacesIps; let idx = index;" [ngValue]="obj.id">
{{ obj.name }} ({{obj.address}})
</option>
</select>
</div>
Upvotes: 1
Reputation: 669
you can subscribe to the network_interface
form control value change as follows;
this.network_interface.valueChanges.subscribe(val => {
// your code here
});
you may also want to change [value]
to [ngValue]
if you're working with non string values
Upvotes: 1