ฉันจะเรียกไปป์ Angular 2 พร้อมอาร์กิวเมนต์หลายตัวได้อย่างไร


204

ฉันรู้ว่าฉันสามารถโทรหาท่อเช่นนี้ได้:

{{ myData | date:'fullDate' }}

ที่นี่ไพพ์วันที่ใช้อาร์กิวเมนต์เดียวเท่านั้น ไวยากรณ์ในการเรียกไพพ์ที่มีพารามิเตอร์มากขึ้นคืออะไรจากเทมเพลต HTML ขององค์ประกอบและในรหัสโดยตรง

คำตอบ:


404

ในแม่แบบของคอมโพเนนต์คุณสามารถใช้อาร์กิวเมนต์หลายตัวโดยแยกพวกเขาด้วยเครื่องหมายโคลอน:

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

เบต้า 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];
        ...
    }
}

8
การออกแบบนี้โง่ ฉันต้องตรวจสอบเอกสารทุกครั้งที่เจอปัญหานี้
tom10271

เท็มเพลตบิตจะมีลักษณะเป็นอย่างไรarg1และarg2ทั้งคู่เป็นตัวเลือกและคุณต้องการส่งต่อarg2หรือไม่
Freethebees

ถ้าคุณผ่านundefinedเป็นอาร์กิวเมนต์แรกมันจะได้รับค่าเริ่มต้น
Eran Shabi

3
ปัจจุบันแทนการtransform(value:any, arg1:any, arg2:any, arg3:any)ใช้ประกอบการส่วนที่เหลือรู้สึกดีขึ้นผมคิดว่า:transform(value:any, ...args:any[])
MKB

เหตุใดการแปลง (... args) ทำให้เกิดข้อผิดพลาด แต่การแปลง (ค่า ... args) ไม่ใช่
Sh eldeeb

45

คุณไม่มีไพพ์จริง

{{ myData | date:'fullDate' }}

พารามิเตอร์หลายตัวสามารถคั่นด้วยโคลอน (:)

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

นอกจากนี้คุณยังสามารถเชื่อมโยงท่อเช่น:

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

25

ตั้งแต่ 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

ไพพ์ตอนนี้รับจำนวนตัวแปรที่ขัดแย้งกันและไม่ใช่อาเรย์ที่มีอาร์กิวเมนต์ทั้งหมด


เท็มเพลตบิตจะมีลักษณะเป็นอย่างไรarg1และarg2ทั้งคู่เป็นตัวเลือกและคุณต้องการส่งต่อarg2หรือไม่
Freethebees

เราสามารถใช้ชื่อตัวแปรต่าง ๆ นอกเหนือจากนี้ได้arg1หรือไม่? กดisFullDateไลค์ ฉันแค่ถามเพราะทุกตัวอย่างใช้สิ่งนี้
sabithpocker

'arg1'และ'arg2'เป็นเพียงตัวอักษรสตริงที่ส่งผ่านเป็นพารามิเตอร์เพิ่มเติมไปยังท่อ คุณสามารถใช้ค่าหรือการอ้างอิงใด ๆ ที่มีอยู่ในขอบเขตนั้น (อินสแตนซ์ขององค์ประกอบปัจจุบัน)
GünterZöchbauer

1
@freethebees คุณต้องผ่านโมฆะ
karoluS

วิธีการแปลงไม่รองรับอาร์เรย์ที่มีจุดดี @Gunter
BALS

5

ฉันใช้ Pipes ใน Angular 2+ เพื่อกรองอาร์เรย์ของวัตถุ ต่อไปนี้ใช้อาร์กิวเมนต์ตัวกรองหลายตัว แต่คุณสามารถส่งหนึ่งข้อโต้แย้งได้หากคุณต้องการ นี่คือตัวอย่าง StackBlitz มันจะค้นหากุญแจที่คุณต้องการกรองแล้วกรองตามมูลค่าที่คุณจัดหา มันเป็นจริงค่อนข้างง่ายถ้าเสียงมันซับซ้อนก็ไม่ได้ตรวจสอบตัวอย่าง StackBlitz

นี่คือท่อที่ถูกเรียกในคำสั่ง * 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

ตัวอย่าง GitHub: คัดลอกสำเนาการทำงานของตัวอย่างนี้ที่นี่

* โปรดทราบว่าในคำตอบของ Gunter, Gunter ระบุว่าอาร์เรย์ไม่ได้ใช้เป็นอินเตอร์เฟสตัวกรองอีกต่อไป แต่ฉันค้นหาลิงค์ที่เขาให้และพบว่าไม่มีอะไรพูดถึงการอ้างสิทธิ์นั้น นอกจากนี้ตัวอย่าง StackBlitz ที่มีให้แสดงรหัสนี้ทำงานตามที่ตั้งใจไว้ใน Angular 6.1.9 มันจะทำงานใน Angular 2+

Happy Coding :-)


ไม่มีจุดในการผ่านอาร์เรย์เดียวที่มีหลายรายการแทนที่จะส่งพารามิเตอร์ multple ไปยังไพพ์โดยตรง
BrunoJCM

อาร์เรย์มีวัตถุ วัตถุสามารถมีคู่ค่าคีย์หลายคู่ที่ใช้ในการสร้างแบบสอบถามแบบไดนามิกที่คุณสามารถค้นหาระเบียนที่ตรงกันโดยใช้ชื่อคอลัมน์เปรียบเทียบกับค่าแถวของคอลัมน์ คุณจะไม่ได้รับการสืบค้นแบบไดนามิกในระดับนี้ผ่านพารามิเตอร์ CSV
3777549

-2

ขยายจาก: ผู้ใช้3777549

ตัวกรองหลายค่าในชุดข้อมูลหนึ่งชุด (อ้างอิงถึงคีย์ชื่อเท่านั้น)

HTML

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

filterMultiple

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);
      }
    })
  });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.