I am much more familiar with React. My problem seems quite common.
First of all I have a TreeDataStructure class. Within this class, I have a 'filters' property that holds the filters applied to the tree in memory.
The tree is stored in the property of a component A. I transfer the 'filters' property of the tree to a component B, child of A.
This child displays all the filters one by one, and a component C, child of B, displays a single filter and allows it to be modified.
My concern is that I can't get the filter changes from C to the TreeDataStructure class stored in component A.
Here is the gist of my code:
TreeDataStructure.ts
export class DataTreeStructure {
filters: Filters;
}
type Filters = {
items: Array<Filter>
linkOperator: LinkOperator //and or or
}
type Filter = {
column: string
operator: string
comparaisonValue: string
}
Component A
export class ComponentA {
tree: DataTreeStructure
}
Component A Template
<component-b filters[tree.filters]></component-b>
Component B
export class ComponentB {
@Input() filters: Filters;
}
Component B Template
<ng-container *ngFor="let item of filters.items; let index = index;">
<component-c
[column]="filters.items[index].column"
[operator]="filters.items[index].operator"
[comparaisonValue]="filters.items[index].comparaisonValue"
>
</component-c>
</ng-container>
Component C
export class ComponentC {
@Input() column: string;
@Input() operator: string;
@Input() comparaisonValue: string;
}
Component C Template
<input [(ngModel)]="column"/>
<input [(ngModel)]="operator"/>
<input [(ngModel)]="comparaisonValue"/>
How would you do it?
CodePudding user response:
To update the filters property of the TreeDataStructure class from the Component C, you can use a combination of Input and Output decorators. Here's one way to do it:
Create an Output event emitter in Component C to emit the updated filter values.
@Output() filterChanged = new EventEmitter<Filter>();
In the template of Component C, emit the event when the filter values are changed.
<input [(ngModel)]="column" (ngModelChange)="emitFilterChanged()"/>
<input [(ngModel)]="operator" (ngModelChange)="emitFilterChanged()"/>
<input [(ngModel)]="comparaisonValue"
(ngModelChange)="emitFilterChanged()"/>
In the Component C class, create a method to emit the event with the updated filter values.
emitFilterChanged() {
this.filterChanged.emit({
column: this.column,
operator: this.operator,
comparaisonValue: this.comparaisonValue
});
}
In Component B, create a method to handle the filterChanged event and update the filters property of the TreeDataStructure class.
handleFilterChanged(filter: Filter, index: number) {
this.filters.items[index] = filter;
}
In the template of Component B, pass the index of the filter and the handleFilterChanged method to the Component C and bind the filterChanged event to the handleFilterChanged method.
<ng-container *ngFor="let item of filters.items; let index = index;">
<component-c
[column]="filters.items[index].column"
[operator]="filters.items[index].operator"
[comparaisonValue]="filters.items[index].comparaisonValue"
(filterChanged)="handleFilterChanged($event, index)"
>
</component-c>
</ng-container>
By using this method, you can now update the filters property of the TreeDataStructure class from the Component C, and the changes will be reflected in Component A.