2016-04-12 27 views
5

Bileşenin içinde bir liste için kullanılması gereken bir boruyu geçirebileceğiniz bir bileşen oluşturmaya çalışıyorum. ne tek çözüm test ve cevaplar için etrafa tarafından bulabildiğim gibi bir şey oluşturmak için görünen Gönderen:Angular 2'de dinamik boru

<my-component myFilter="sortByProperty"></my-component> 

my-component şablonu:

<li *ngFor="#item of list | getPipe:myFilter"></li> 

sonra doğru boru mantığına myFilter eşler ve onu çalıştırır ama bu biraz kirli ve optimal değil gibi görünüyor.

Bu hatlar boyunca bir şeyler yapacağınız Açısal 1'den beri bu problem için daha iyi bir çözüm bulmuş olacaklarını düşünmüştüm.

Angular 2'de bunu yapmanın daha iyi bir yolu yok mu?

+0

özel filtrenize mi geçiyor? –

cevap

3

Maalesef öyle düşünmüyorum. İstediğiniz dinamik boru için bir işlev döndürdüğünüzde, köşeli1 ile aynıdır.

Tam olarak nasıl göründüklerini gösteren belgelere bakın. Sonra denetleyicisi

https://angular.io/docs/ts/latest/guide/pipes.html

template: ` 
    <p>The hero's birthday is {{ birthday | date:format }}</p> 
    <button (click)="toggleFormat()">Toggle Format</button> 
` 

:

get format() { return this.toggle ? 'shortDate' : 'fullDate'} 

Ne yazık ki, daha kötü olabilirdi! :)

1

Çalışırken bir şeyler elde etmeyi başardım, biraz kirli ve kötüydü (eval ile) ama benim için hile yapıyor. Benim durumumda, her satırda farklı veri türleri olan bir tablo bileşenim var (ör. Başlık, url, tarih, durum). Veritabanımda olarak enabled olarak veya disabled için 0 olarak işaretlenir. Tabii ki, kullanıcı için etkin/devre dışı gösterilmek daha tercih edilir. Ayrıca, başlık sütunum çok dillidir, bu da onu bir anahtar olarak en veya id ile bir nesne yapar.

// Example row object: 
title: { 
    "en": "Some title in English", 
    "id": "Some title in Indonesian" 
}, 
status: 1 // either 1 or 0 

İdeal olarak, verilerimi uygulamamın kullanıcılarına gösterecek şekilde dönüştürmek için 2 farklı boruya ihtiyacım var. translateTitle ve getStatus gibi bir şey iyi durumda. Ebeveynin borusunu dynamicPipe numaralı telefondan arayalım.

/// some-view.html 
{{ title | dynamicPipe:'translateTitle' }} 
{{ status | dynamicPipe:'getStatus' }} 


/// dynamic.pipe.ts 
//...import Pipe and PipeTransform 

@Pipe({name:'dynamicPipe'}) 
export class DynamicPipe implements PipeTransform { 

    transform(value:string, modifier:string) { 
     if (!modifier) return value; 
     return eval('this.' + modifier + '(' + value + ')') 
    } 

    getStatus(value:string|number):string { 
     return value ? 'enabled' : 'disabled' 
    } 

    translateTitle(value:TitleObject):string { 
     // defaultSystemLanguage is set to English by default 
     return value[defaultSystemLanguage] 
    } 
} 

Muhtemelen eval kullanarak çok fazla nefret alacağım. Umarım yardımcı olur!

Güncelleme: Eğer zaman ihtiyacınız olacağını

posts = { 
    content: [ 
     { 
      title: 
       { 
        en: "Some post title in English", 
        es: "Some post title in Spanish" 
       }, 
      url: "a-beautiful-post", 
      created_at: "2016-05-15 12:21:38", 
      status: 1 
     }, 
     { 
      title: 
       { 
        en: "Some post title in English 2", 
        es: "Some post title in Spanish 2" 
       }, 
      url: "a-beautiful-post-2", 
      created_at: "2016-05-13 17:53:08", 
      status: 0 
     } 
    ], 
    pipes: ['translateTitle', null, 'humanizeDate', 'getStatus'] 
} 

<table> 
    <tr *ngFor="let row in posts"> 
     <td *ngFor="let column in row; let i = index">{{ column | dynamicPipe:pipes[i] }}</td> 
    </tr> 
</table> 

döndürür:

| title   | url   | date   | status   | 
| Some post t... a-beautiful... an hour ago  enabled 
| Some post ...2 a-beautifu...2 2 days ago  disabled 
2

yerine HTML şablonları boruları kullanmak değil olurdu bu mücadele etmenin en kolay yolu, enjekte boruyu bir bileşenin yapıcısına (DI kullanarak) dönüştürün, sonra dönüşümü işlevsel olarak uygulayın. Bu Gözlemlenebilir bir harita veya benzer rxjs akışları ile oldukça iyi çalışır.

+0

İyi bir öneri, ancak istediğim şekilde kullanılacaksa bir sarıcı hizmete gerek duyardı. – Chrillewoodz

2

borislemke cevabı üzerine inşa edilen Burada eval() ihtiyacı olmayan bir çözüm ve hangi doğrusu temiz bulmak:

dynamic.pipe.ts:

import { 
    Injector, 
    Pipe, 
    PipeTransform 
} from '@angular/core'; 


@Pipe({ 
    name: 'dynamicPipe' 
}) 
export class DynamicPipe implements PipeTransform { 

    public constructor(private injector: Injector) { 
    } 

    transform(value: any, pipeToken: any, pipeArgs: any[]): any { 
     if (!pipeToken) { 
      return value; 
     } 
     else { 
      let pipe = this.injector.get(pipeToken); 
      return pipe.transform(value, ...pipeArgs); 
     } 
    } 
} 

app.module.ts:

// … 
import { DynamicPipe } from './dynamic.pipe'; 

@NgModule({ 
    declarations: [ 
    // … 
    DynamicPipe, 
    ], 
    imports: [ 
    // … 
    ], 
    providers: [ 
    // list all pipes you would like to use 
    PercentPipe, 
    ], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { } 

app.component.ts:

import { Component, OnInit } from '@angular/core'; 
import { PercentPipe } from '@angular/common'; 

@Component({ 
    selector: 'app-root', 
    template: ` 
    The following should be a percentage: 
    {{ myPercentage | dynamicPipe: myPipe:myPipeArgs }} 
    `, 
    providers: [] 
}) 

export class AppComponent implements OnInit { 
    myPercentage = 0.5; 
    myPipe = PercentPipe; 
    myPipeArgs = []; 
}