Home > Blockchain >  Update an object array via ngmodel from a child component Angular
Update an object array via ngmodel from a child component Angular

Time:01-13

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.

  • Related