Angular 2管道:在单个ng

时间:2017-03-17 09:27:22

标签: sorting angular pipe

以下是JSON数据:

{
  "tagFrequency": [
    {
      "value": "At",
      "count": 1,
      "tagId": 249
    },
    {
      "value": "ipsum",
      "count": 1,
      "tagId": 251
    },
    {
      "value": "molestie",
      "count": 1,
      "tagId": 199
    }
  ]
}

我在UI中将这些数据填充到一个表中,该表的列名为word,频率分别为上面的JSON对象属性值和count。使用tagId属性通过GET API调用提取第三列标记名称。以下是我的HTML代码:

<table>
  <thead>
    <tr>
      <th (click)="sort('value')">{{ 'word' | translate }}</th>
      <th (click)="sort('tagId')">{{ 'tag-name' | translate }}</th>
      <th (click)="sort('count')">{{ 'frequency' | translate }}</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let frequency of (frequencies | TagFrequencySorter: key: direction); let i = index;">
      <td>{{ frequency.value }}</td>
      <td>{{ processedTagNames[i] }}</td>
      <td>{{ frequency.count }}</td>
    </tr>
  </tbody>
</table>

我想对这些列值和计数进行排序,这与“TagFrequencySorter”管道一起使用。但我也想在同一个for循环中使用相同的管道对tagNames数组数据进行排序。我可以在管道中进行必要的更改,但我想要的是将这两个数组以某种方式传递给此管道。

以下是我在组件中编写的排序函数:

sort(value: string) {
    this.direction = this.direction * (-1);
    if(value === "tagId") {
      this.key = "";
    }
    else {
      this.key = value;
    }
  }

这是管道实现:

export class TagFrequencySorter implements PipeTransform {
  transform(tagFrequencies: any, key: string, direction: number): any[] {
    if (key !== '' && tagFrequencies !== null) {
      console.log(key)
      tagFrequencies.sort(
        (a: any, b: any) => {
          let propertyA: number|string = this.getProperty(a, key);
          let propertyB: number|string = this.getProperty(b, key);

          if (propertyA < propertyB) {
            return -1 * direction;
          } else if (propertyA > propertyB) {
            return 1 * direction;
          } else {
            return 0;
          }
        }
      );
    }
    return tagFrequencies;
  }

  private getProperty(value: { [key: string]: any}, key: string): number|string {
    if (value === null || typeof value !== 'object') {
      return undefined;
    }
    let keys: string[] = key.split('.');
    let result: any = value[keys.shift()];
    for (let newkey of keys) {
      if (result === null) {
        return undefined;
      }
      result = result[newkey];
    }
    return result;
  }
}

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

实现此目的的一种方法是通过将自定义管道作为提供程序传递给组件来预处理tagNames数组

constructor(private _tagFrequencySorterPipe: TagFrequencySorter){ }

get processedTagNames(){
    return this._tagFrequencySorterPipe(this.tagNames, this.key, this.direction);    
}

您的HTML将如下所示:

<tr *ngFor="let frequency of (frequencies | TagFrequencySorter: key: direction); let i = index;">
    <td>{{ frequency.value }}</td>
    <td>{{ processedTagNames[i] }}</td>
    <td>{{ frequency.count }}</td>
</tr>

有关Angular2中管道依赖项注入的详细信息,请参阅此question

另一个选项可能是merge the two arrays使用单独的管道,然后修改现有的排序管道以处理合并的数组:

<tr *ngFor="let item of (frequencies | merge: tagNames |TagFrequencySorter: key: direction); let i = index;">
    <td>{{ item.frequency.value }}</td>
    <td>{{ item.tagName }}</td>
    <td>{{ item.frequency.count }}</td>
</tr>