How to save detection of changes during transfer of the user "request" -object to a tube instead of a line (Angular 2)?

(TL; DR: summary of questions found below)

Hi guys.

I have a large dataset that I want to filter using several criteria. All this worked fine, but I had to do some unpleasant things that I want to get rid of.

I use the angular2 -datatable package, but I think the problem is rather somewhere in my understanding of angular. So one of the most unpleasant things was that I had to create one tube for each filter criterion.

<table class="table table-striped" [mfData]="(((data | wstateFilter : filterQuery.wstate ) | dataSubjectFilter : filterQuery.subject) | dataResponsibilityFilter : filterQuery.personResponsible) | issuedByFilter : filterQuery.issuedBy" #mf="mfDataTable">

Now this may not seem too nasty, but later at least 20-50 pipes may explode in just 4 data sets.

I want to define a FilterQuery object that contains all the filter criteria, and one corresponding channel that accepts these objects as queries.

<table [mfData]="((data | dataSetFilter : filterQuery" #mf="mfDataTable">

Now the request object looks like this:

export class TaskQuery {
    public subject: string;
    public wstate: TaskWorkstate;
    public personResponsible: string;
    public issuedBy?: string;
}

I defined Pipe as follows:

import * as _ from "lodash"
import { Pipe, PipeTransform } from "@angular/core";
import { Task, TaskQuery } from './task.import'

@Pipe({
     name: "dataSetFilter"
     })
export class QueryPipe implements PipeTransform {
    transform(array: Task[], query: TaskQuery): any {
        array = _.filter(array, function (o) {
            if (!(o.subject.indexOf(query['subject']) > -1)) return false;
            if (o['personResponsible'].indexOf(query['personResponsible']) < 0) return false;
            if (o.hasOwnProperty('issuedBy')) {
                if (o['issuedBy'].indexOf(query['issuedBy']) < 0) return false;
            }
            return true;
        });
        return array;
    }
}

So far, the pipe works so well, as expected. For hard-coded TaskQuery objects, the pipe does what I want. The problem starts when I want to use data binding to the variables of a TaskQuery object.

For instance:

 <input class="form-control" [(ngModel)]="filterQuery.personResponsible" />

If this is done, change detection does not start and data does not pass through the pipe. I think because Angular is probably just looking at a reference to an object filterQuerythat obviously remains the same.

This simple workaround does not work ...

<input class="form-control" [ngModel]="filterQuery.subject" (ngModelChange)="temp=filterQuery; temp.setSubject($event); filterQuery=temp" />

... because objects are passed by reference: - (.

, Angular let new . .

, :

  • - ? ( )

  • ? (, <input class="form-control" [ngModel]="filterQuery.subject" (ngModelChange)="temp=new FilterQuery().copy(filterQuery); temp.setSubject($event); filterQuery=temp"> )

+4
1

, newQuery() xyz.component.ts, (ngModelChange)="filterQuery.set('subject', $event); newQuery()"

newQuery()

public newQuery(): void {
    this.filterQuery = Object.assign(new TaskQuery(), filterQuery);
}

, - - . , .

0

Source: https://habr.com/ru/post/1664178/


All Articles