Hi I am now working on angular to build a multiselect dropdown using ng-multiselect-dropdown(https://www.npmjs.com/package/ng-multiselect-dropdown).
I used parent-child component communication through event emitter: in child.component.ts:
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {IDropdownSettings} from 'ng-multiselect-dropdown';
export interface IMultiDropdownConfig {
placeholder: string;
header: string;
dropdownSettings: IDropdownSettings;
}
@Component({
selector: 'app-multi-dropdown',
templateUrl: './multi-dropdown.component.html',
styleUrls: ['./multi-dropdown.component.scss']
})
export class MultiDropdownComponent implements OnInit {
@Input() dropdownItems: any[];
@Input() selectedItems;
@Input() header: string;
@Input() placeholder: string;
@Input() dropdownSettings: IDropdownSettings;
@Input() loading;
@Output() itemSelectEvent = new EventEmitter();
@Output() itemDeselectEvent = new EventEmitter();
@Output() selectAllEvent = new EventEmitter();
@Output() deselectAllEvent = new EventEmitter();
@Output() selectedItemsChange = new EventEmitter();
constructor() { }
ngOnInit(): void {
}
onSelectItem(event) {
this.selectedItemsChange.emit(this.selectedItems);
}
onDeselectItem(event) {
this.selectedItemsChange.emit(this.selectedItems);
}
onSelectAll(event) {
this.selectedItemsChange.emit(this.selectedItems);
}
onDeselectAll(event) {
this.selectedItemsChange.emit(this.selectedItems);
}
}
in child.component.html:
<div class="multi-dropdown-item">
<div class="multi-dropdown-header">{{header}}</div>
<div *ngIf="!this.loading" class="multi-dropdown-body">
<ng-multiselect-dropdown
[placeholder]="placeholder"
[data]="dropdownItems"
[(ngModel)]="selectedItems"
[settings]="dropdownSettings"
(onSelect)="onSelectItem($event)"
(onDeSelect)="onDeselectItem($event)"
(onSelectAll)="onSelectAll($event)"
(onDeSelectAll)="onDeselectAll($event)">
</ng-multiselect-dropdown>
</div>
</div>
Then in parent.component.html:
<app-multi-dropdown
[loading]="filterPropertiesMap.get(filterEntry).loading"
[dropdownItems]="filterPropertiesMap.get(filterEntry).items"
[(selectedItems)]="filterPropertiesMap.get(filterEntry).selectedItems"
[dropdownSettings]="filterPropertiesMap.get(filterEntry).setting"
[placeholder]="filterPropertiesMap.get(filterEntry).name"
[header]="filterPropertiesMap.get(filterEntry).name"
(itemSelectEvent)="onItemSelect($event)"
(itemDeselectEvent)="onItemDeselect($event)"
(selectAllEvent)="onSelectAll($event)"
(deselectAllEvent)="onDeselectAll($event)"
></app-multi-dropdown>
in parent.component.ts I didn't do anything but log:
onItemSelect($event) {
console.log("onItemSelect");
}
onItemDeselect($event) {
console.log("onItemDeselect");
}
onSelectAll($event) {
console.log("onSelectAll");
}
onDeselectAll($event) {
console.log("onDeselectAll");
}
in above code filterPropertiesMap defines settings.
You may see that what I am doing is in child component, I created eventemitters for select, deselect, and in the function I emitt this.selectedItems.
But I don't think this is a good way to implement this, and actually, it doesn't work well. sometimes, when I select or deselect, it doesn't changed immediately.
So how to implement this? when I select deselect, selectAll, deselectAll. my parent component can react immediately and correctly.
Also the weird thing is: when I load the page, I will have some default values chose, for example 6,7,8,9. Then I select all and it still 6,7,8,9. and then after that I deselect all agin select all, the field will change to all(for example 1,2,3,4,5,6,7,8,9). Does event emitter has delay or will ignore some choices??
Edit:
I tried to extract all the necessary snippets of code to build a project here: https://drive.google.com/file/d/1BlV2EtdwZhqqpkdiC0_mlaw_r3w6Bder/view?usp=sharing
I hope when I all the event(select, deselect, selectAll, deselectAll) can be emitted and received by parent component
sorry one mistake: the app-multi-dropdown tag in parent component should be app-child