4

(TL;DR: Summary of questions is found below)

I have a large data set which I want to filter using multiple criteria. It's all working nicely however I had to do some nasty things which I want to get rid of.

I'm using the angular2-datatable package, but I guess the problem rather lies somewhere in my lack of understanding of angular. So one of the nastier things was that I had to create one pipe per filter criteria.

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

This may not look too nasty now, but this might later explode into at least 20-50 pipes for just 4 Datasets.

I want to define a FilterQuery Object that contains all filter criteria, and one corresponding pipe that takes these objects as queries.

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

The query object now looks like:

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

I have defined the Pipe like this:

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 so good the pipe is working as it is supposed to. For hard-coded TaskQuery objects the pipe does what I want. The problem starts when I want to use databinding to the variables of the TaskQuery object.

For example:

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

When this is done the change detection isn't triggered and the data is not put through the pipe. I guess because Angular probably just looks at the reference to the object filterQuery, which obviously remains the same.

This simple workaround doesn't work either:

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

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

Furthermore angular doesn't let me execute let or new statements in templates. Therefore I cannot create a new reference so far.

So questions:

  • Is it possible to mark an object somehow as changed? (this is what I would actually want)

  • How can I create a new object reference in the template file? (Like e.g. <input class="form-control" [ngModel]="filterQuery.subject" (ngModelChange)="temp=new FilterQuery().copy(filterQuery); temp.setSubject($event); filterQuery=temp"> )

peterh
  • 11,875
  • 18
  • 85
  • 108
KayleeTheMech
  • 489
  • 1
  • 4
  • 17
  • 1
    Have you tried to create new object like `filterQuery = Object.assign({}, filterQuery)` Check also this http://stackoverflow.com/questions/39941185/dynamically-updating-checked-in-angular2 – yurzui Dec 19 '16 at 14:36
  • Hi, I eventually ended up doing exactly that. My main limitation was that I wanted to write the code for that into the template... which didn't work. – KayleeTheMech Dec 19 '16 at 17:53

1 Answers1

1

I made it work by defining a method newQuery() in the xyz.component.ts that may be called from the template with (ngModelChange)="filterQuery.set('subject', $event); newQuery()"

The function newQuery() generates a new reference and overwrites the old one by

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

I'm not entirely satisfied, because it still feels like a not-so-dirty work around. However, it erases the majority of the drawbacks so far.

KayleeTheMech
  • 489
  • 1
  • 4
  • 17