I have a dynamic array of ng-select controls. Each control represented by class NgSelectComponent.
When select value changes I want to subscribe to all controls.
Template
<ng-select #select">
<ng-option *ngFor="let option of options" [value]="select.id">{{ option.name }}</ng-option>
</ng-select>
Class
@ViewChildren('select') controls: QueryList<NgSelectComponent>;
ngAfterViewInit() {
concat(this.controls.toArray()).subscribe(x => {
console.log(x);
});
}
I try that, but does not work.
concat(this.components.toArray()).subscribe(x => {
console.log(x);
});
I believe it does not work because I had to subscribe to the values produced by each control corresponded by changeEvent but struggling to do that.
Any ideas how to solve?
CodePudding user response:
First of all, concat
will likely not work. With concat
, each observable in the array will wait for the previous to complete. This is probably not the behaviour you are expecting here.
You may use merge
which will simply forwards all the emitted values to the output Observable individually. Or use combineLatest
if you want an array of all the current values, whenever one Observable emits.
To convert the valueChanges
of the controls
to an array, use a map
.
merge(
...this.controls.toArray().map(c => c.changeEvent.asObservable())
).subscribe(x => {
console.log(x);
});
CodePudding user response:
This is what Reactive Forms are for. You create a FormArray
and have FormControl
s in there. Then you can subscribe to the valueChanges
observable of the FormControl
s. I highly recommend you to rewrite the code using this angular feature.
That being said, the easiest and more let's say unrefined solution is to use the changeEvent as you said:
<ng-select #select (change)="selectChanged($event)">
<ng-option *ngFor="let option of options" [value]="select.id">{{ option.name }}</ng-option>
</ng-select>
selectChanged($event) {
// This function is called every time any select is changed.
// If you want, you can create a Subject and .next() the values there to have an Observable
console.log($event.target.value);
}