角度2排序和过滤器

ale*_*are 73 typescript angular

在Angularjs 1中,可以按以下方式排序和过滤:

<ul ng-repeat="friend in friends | filter:query | orderBy: 'name' ">
   <li>{{friend.name}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

但我在Angularjs 2.0中找不到任何如何做到这一点的例子.我的问题是如何在Angularjs 2.0中进行排序和过滤?如果它仍然不受支持,是否有人知道何时或是否将它放入Angularjs 2.0?

Cor*_*haw 79

这不是开箱即用的,因为Angular团队希望Angular 2能够进行缩小.OrderBy运行了反射,它会缩小.查看MiškoHeyy对此事的回应.

我花时间创建了一个支持单维和多维数组的OrderBy管道.它还支持能够对多维数组的多个列进行排序.

<li *ngFor="let person of people | orderBy : ['-lastName', 'age']">{{person.firstName}} {{person.lastName}}, {{person.age}}</li>
Run Code Online (Sandbox Code Playgroud)

此管道允许在呈现页面后向阵列添加更多项目,并仍然正确地使用新项目对数组进行排序.

在这里写了一篇关于这个过程的文章.

这是一个有效的演示:http://fuelinteractive.github.io/fuel-ui/#/pipe/orderbyhttps://plnkr.co/edit/DHLVc0?p=info

编辑:添加了新的演示到http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby

编辑2:更新了ng对新语法

  • 小更新.最新的Angular2*ngFor将使用*ngFor ="让人们...而不是#标签# (2认同)
  • @CoryShaw伟大的烟斗!做得好****拍手表情符号***** (2认同)
  • @invot 正确,这个管道只是 orderBy 功能。应在阵列上使用第二个管道进行过滤。下面选择的答案是过滤的一个很好的例子 (2认同)
  • @ 72GM多维实际上是`[] []`,所以你是对的.多层次的措辞会更好吗?`[] .SomeObjectProperty.SomeProperty` (2认同)

tre*_*eat 19

它不受设计支持.sortBy管道可能会导致生产规模应用程序出现真正的性能问题.这是角度版本1的问题.

您不应该创建自定义排序功能.相反,您应该首先在typescript文件中对数组进行排序,然后显示它.如果在选择下拉列表时需要更新订单,则让此下拉列表选项触发一个函数并调用从中调用的排序函数.可以将此排序功能提取到服务中,以便可以重复使用它.这样,只有在需要时才会应用排序,并且您的应用程序性能会更好.


sel*_*ect 18

这是一个简单的过滤管道,用于包含带字符串值的属性的对象数组(ES6)

filter-array-pipe.js

import {Pipe} from 'angular2/core';

// # Filter Array of Objects
@Pipe({ name: 'filter' })
export class FilterArrayPipe {
  transform(value, args) {
    if (!args[0]) {
      return value;
    } else if (value) {
      return value.filter(item => {
        for (let key in item) {
          if ((typeof item[key] === 'string' || item[key] instanceof String) && 
              (item[key].indexOf(args[0]) !== -1)) {
            return true;
          }
        }
      });
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

你的组件

myobjComponent.js

import {Component} from 'angular2/core';
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import {FilterArrayPipe} from 'filter-array-pipe';

@Component({
  templateUrl: 'myobj.list.html',
  providers: [HTTP_PROVIDERS],
  pipes: [FilterArrayPipe]
})
export class MyObjList {
  static get parameters() {
    return [[Http]];
  }
  constructor(_http) {
    _http.get('/api/myobj')
      .map(res => res.json())
      .subscribe(
        data => this.myobjs = data,
        err => this.logError(err))
      );
  }
  resetQuery(){
    this.query = '';
  }
}
Run Code Online (Sandbox Code Playgroud)

在您的模板中

myobj.list.html

<input type="text" [(ngModel)]="query" placeholder="... filter" > 
<div (click)="resetQuery()"> <span class="icon-cross"></span> </div>
</div>
<ul><li *ngFor="#myobj of myobjs| filter:query">...<li></ul>
Run Code Online (Sandbox Code Playgroud)


Nic*_*ert 13

管道将数据作为输入并将其转换为所需的输出.添加此管道文件:orderby.ts在您的/app文件夹中.

orderby.ts

//The pipe class implements the PipeTransform interface's transform method that accepts an input value and an optional array of parameters and returns the transformed value.

import { Pipe,PipeTransform } from "angular2/core";

//We tell Angular that this is a pipe by applying the @Pipe decorator which we import from the core Angular library.

@Pipe({

  //The @Pipe decorator takes an object with a name property whose value is the pipe name that we'll use within a template expression. It must be a valid JavaScript identifier. Our pipe's name is orderby.

  name: "orderby"
})

export class OrderByPipe implements PipeTransform {
  transform(array:Array<any>, args?) {

    // Check if array exists, in this case array contains articles and args is an array that has 1 element : !id

    if(array) {

      // get the first element

      let orderByValue = args[0]
      let byVal = 1

      // check if exclamation point 

      if(orderByValue.charAt(0) == "!") {

        // reverse the array

        byVal = -1
        orderByValue = orderByValue.substring(1)
      }
      console.log("byVal",byVal);
      console.log("orderByValue",orderByValue);

      array.sort((a: any, b: any) => {
        if(a[orderByValue] < b[orderByValue]) {
          return -1*byVal;
        } else if (a[orderByValue] > b[orderByValue]) {
          return 1*byVal;
        } else {
          return 0;
        }
      });
      return array;
    }
    //
  }
}
Run Code Online (Sandbox Code Playgroud)

在组件文件(app.component.ts)中,使用以下命令导入刚刚添加的管道: import {OrderByPipe} from './orderby';

然后,*ngFor="#article of articles | orderby:'id'"如果要按ID按升序或orderby:'!id'"降序对文章进行排序,请在模板内添加.

我们通过使用冒号(:)跟随管道名称然后输入参数值来向管道添加参数

我们必须在@Component装饰器的pipes数组中列出我们的管道.pipes: [ OrderByPipe ].

app.component.ts

import {Component, OnInit} from 'angular2/core';
import {OrderByPipe} from './orderby';

@Component({
    selector: 'my-app',
    template: `
      <h2>orderby-pipe by N2B</h2>
      <p *ngFor="#article of articles | orderby:'id'">
        Article title : {{article.title}}
      </p>
    `,
    pipes: [ OrderByPipe ]

})
export class AppComponent{
    articles:Array<any>
    ngOnInit(){
        this.articles = [
        {
            id: 1,
            title: "title1"
        },{
            id: 2,
            title: "title2",
        }]  
    }

}
Run Code Online (Sandbox Code Playgroud)

更多信息在我的github我的网站上的这篇文章

  • 我喜欢这种结构化的方式,易于理解.谢谢.但是,请在此处和您的网站/ github上更新您的脚本.在第一行中将"angular2/core"更改为"@ angular/core".除此之外,一开始我无法让它工作,然后我飞过你的代码并意识到你的"模板"步骤有一个很大的错字.在模板中,它必须是一个数组,以便按预期工作:"| orderby:['id']" (4认同)

Vla*_*vic 4

您必须创建自己的 Pipe 来进行数组排序,下面是如何做到这一点的一个示例。

<li *ngFor="#item of array | arraySort:'-date'">{{item.name}} {{item.date | date:'medium' }}</li>
Run Code Online (Sandbox Code Playgroud)

https://plnkr.co/edit/DU6pxr?p=preview

  • 他们为什么不提供开箱即用的功能?这是很常见的事情,他们不提供这一点真是可笑。 (10认同)
  • 这没有意义......上述所有解决方案都可以缩小,不是吗?这么大的一个框架怎么能省略这么基本的功能呢…… (2认同)