【问题标题】:How do I call an Angular 2 pipe with multiple arguments?如何调用具有多个参数的 Angular 2 管道?
【发布时间】:2016-08-17 10:33:47
【问题描述】:

我知道我可以这样调用管道:

{{ myData | date:'fullDate' }}

这里的日期管道只接受一个参数。 从组件的模板 HTML 和直接在代码中调用具有更多参数的管道的语法是什么?

【问题讨论】:

    标签: javascript angular angular2-pipe


    【解决方案1】:

    在您的组件模板中,您可以使用多个参数,方法是用冒号分隔它们:

    {{ myData | myPipe: 'arg1':'arg2':'arg3'... }}
    

    根据您的代码,它将如下所示:

    new MyPipe().transform(myData, arg1, arg2, arg3)
    

    在管道内的转换函数中,您可以使用如下参数:

    export class MyPipe implements PipeTransform { 
        // specify every argument individually   
        transform(value: any, arg1: any, arg2: any, arg3: any): any { }
        // or use a rest parameter
        transform(value: any, ...args: any[]): any { }
    }
    

    Beta 16 及之前 (2016-04-26)

    管道采用包含所有参数的数组,因此您需要像这样调用它们:

    new MyPipe().transform(myData, [arg1, arg2, arg3...])
    

    您的转换函数将如下所示:

    export class MyPipe implements PipeTransform {    
        transform(value:any, args:any[]):any {
            var arg1 = args[0];
            var arg2 = args[1];
            ...
        }
    }
    

    【讨论】:

    • 这个设计很傻。每次遇到此问题时,我都需要检查文档
    • 如果arg1arg2 都是可选的并且您只想传入arg2,那么模板位会是什么样子?
    • 如果您将undefined 作为第一个参数传递,它将获得其默认值。
    • 现在我认为使用 rest 运算符而不是 transform(value:any, arg1:any, arg2:any, arg3:any) 感觉更好:transform(value:any, ...args:any[])
    • 为什么 transform(...args) 会出错,但 transform(value, ...args) 不会?
    【解决方案2】:

    您缺少实际的管道。

    {{ myData | date:'fullDate' }}
    

    多个参数可以用冒号 (:) 分隔。

    {{ myData | myPipe:'arg1':'arg2':'arg3' }}
    

    你也可以像这样链接管道:

    {{ myData | date:'fullDate' | myPipe:'arg1':'arg2':'arg3' }}
    

    【讨论】:

      【解决方案3】:

      从 beta.16 开始,参数不再作为数组传递给 transform() 方法,而是作为单独的参数:

      {{ myData | date:'fullDate':'arg1':'arg2' }}
      
      
      export class DatePipe implements PipeTransform {    
        transform(value:any, arg1:any, arg2:any):any {
              ...
      }
      

      https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta16-2016-04-26

      管道现在接受可变数量的参数,而不是包含所有参数的数组。

      【讨论】:

      • 如果arg1arg2 都是可选的并且您只想传入arg2,那么模板位会是什么样子?
      • 我们可以使用除arg1之外的不同变量名吗?喜欢isFullDate。我只是问,因为每个示例都使用它。
      • 'arg1''arg2' 只是作为附加参数传递给管道的字符串文字。您可以使用在该范围内可用的任何值或引用(当前组件实例)
      • @freethebees 你必须通过 null
      • 转换方法不支持数组参数好点@Gunter
      【解决方案4】:

      我在 Angular 2+ 中使用管道来过滤对象数组。以下采用多个过滤器参数,但如果适合您的需要,您可以只发送一个。这是StackBlitz Example。它将找到您要过滤的键,然后按您提供的值过滤。这实际上很简单,如果听起来很复杂,请查看StackBlitz Example

      这是在 *ngFor 指令中调用的管道,

      <div *ngFor='let item of items | filtermulti: [{title:"mr"},{last:"jacobs"}]' >
        Hello {{item.first}} !
      </div>
      

      这是管道,

      import { Pipe, PipeTransform } from '@angular/core';
      
      @Pipe({
        name: 'filtermulti'
      })
      export class FiltermultiPipe implements PipeTransform {
        transform(myobjects: Array<object>, args?: Array<object>): any {
          if (args && Array.isArray(myobjects)) {
            // copy all objects of original array into new array of objects
            var returnobjects = myobjects;
            // args are the compare oprators provided in the *ngFor directive
            args.forEach(function (filterobj) {
              let filterkey = Object.keys(filterobj)[0];
              let filtervalue = filterobj[filterkey];
              myobjects.forEach(function (objectToFilter) {
                if (objectToFilter[filterkey] != filtervalue && filtervalue != "") {
                  // object didn't match a filter value so remove it from array via filter
                  returnobjects = returnobjects.filter(obj => obj !== objectToFilter);
                }
              })
            });
            // return new array of objects to *ngFor directive
            return returnobjects;
          }
        }
      }
      

      这里是包含要过滤的对象的组件,

      import { Component } from '@angular/core';
      import { FiltermultiPipe } from './pipes/filtermulti.pipe';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
      })
      export class AppComponent {
        title = 'app';
        items = [{ title: "mr", first: "john", last: "jones" }
         ,{ title: "mr", first: "adrian", last: "jacobs" }
         ,{ title: "mr", first: "lou", last: "jones" }
         ,{ title: "ms", first: "linda", last: "hamilton" }
        ];
      }
      

      StackBlitz Example

      GitHub Example: Fork a working copy of this example here

      *请注意,在 Gunter 提供的回答中,Gunter 声明数组不再用作过滤器接口,但我搜索了他提供的链接,但没有发现任何与该声明相关的内容。此外,提供的 StackBlitz 示例显示此代码在 Angular 6.1.9 中按预期工作。它将在 Angular 2+ 中工作。

      快乐编码:-)

      【讨论】:

      • 传递具有多个条目的单个数组而不是直接将多个参数传递给管道是没有意义的。
      • 数组包含对象。这些对象可以包含多个键值对,用于创建动态查询,您可以在其中使用列名与列的行值进行比较来查找匹配记录。您不会通过 CSV 参数获得这种级别的动态查询。
      【解决方案5】:

      另外,伙计们,如果你像我一样遇到解析器错误,请记住 管道名称不应包含破折号

      @Pipe({ name: 'arrayFilter' }) // I had 'array-filter'
      export class ArrayFilterPipe implements PipeTransform {
          public transform(items: any[], value: string, props: string[]) { ... }
      }
      

      未解析: *ngFor="let workflow of workflows | array-filter: workflowFilter:['Name']; trackBy: trackWorkflow"

      已解析: *ngFor="let workflow of workflows | arrayFilter: workflowFilter:['Name']; trackBy: trackWorkflow"

      【讨论】:

        【解决方案6】:

        扩展自:user3777549

        对一组数据进行多值过滤(仅引用标题键)

        HTML

        <div *ngFor='let item of items | filtermulti: [{title:["mr","ms"]},{first:["john"]}]' >
         Hello {{item.first}} !
        </div>
        

        过滤多个

        args.forEach(function (filterobj) {
            console.log(filterobj)
            let filterkey = Object.keys(filterobj)[0];
            let filtervalue = filterobj[filterkey];
            myobjects.forEach(function (objectToFilter) {
        
              if (!filtervalue.some(x=>x==objectToFilter[filterkey]) && filtervalue != "") {
                // object didn't match a filter value so remove it from array via filter
                returnobjects = returnobjects.filter(obj => obj !== objectToFilter);
              }
            })
          });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-05-11
          • 2014-11-15
          • 2017-10-12
          • 1970-01-01
          • 2018-06-01
          • 1970-01-01
          相关资源
          最近更新 更多