如何在将用户定义的"查询" -Object传递给管道而不是字符串(Angular 2)时保持更改检测活动?

时间:2016-12-19 14:09:34

标签: angular

(TL; DR:问题摘要见下文)

大家好。

我有一个大型数据集,我想使用多个条件进行过滤。这一切都很好,但我不得不做一些我想摆脱的讨厌的东西。

我使用的是angular2-datatable软件包,但我认为问题在于我对角度的理解不足。因此,一个更糟糕的事情是我必须为每个过滤条件创建一个管道。

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

现在看起来可能不太讨厌,但这可能会在4个数据集中爆炸至少20-50个管道。

我想定义一个包含所有过滤条件的FilterQuery对象,以及一个将这些对象作为查询的相应管道。

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

查询对象现在看起来像:

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

我已经像这样定义了管道:

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;
    }
}

到目前为止,管道工作正常。对于硬编码的TaskQuery对象,管道可以满足我的需求。当我想对数据绑定使用TaskQuery对象的变量时,问题就出现了。

例如:

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

完成此操作后,不会触发更改检测,并且不会通过管道传输数据。我想因为Angular可能只是查看对象filterQuery的引用,这显然保持不变。

这个简单的解决方法既不起作用......

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

...因为对象是通过引用传递的: - (。

此外,angular不允许我在模板中执行letnew语句。因此到目前为止我无法创建新的参考文献。

所以问题:

  • 是否可以将某个对象标记为已更改? (这就是我真正想要的)

  • 如何在模板文件中创建新的对象引用? (例如<input class="form-control" [ngModel]="filterQuery.subject" (ngModelChange)="temp=new FilterQuery().copy(filterQuery); temp.setSubject($event); filterQuery=temp">

1 个答案:

答案 0 :(得分:1)

我通过在xyz.component.ts中定义方法newQuery()来实现它,可以使用(ngModelChange)="filterQuery.set('subject', $event); newQuery()"

从模板中调用该方法

函数newQuery()生成一个新引用并用

覆盖旧引用
public newQuery(): void {
    this.filterQuery = Object.assign(new TaskQuery(), filterQuery);
}

我并不完全满意,因为它仍然感觉像是一个不那么肮脏的工作。然而,它消除了迄今为止的大部分缺点。