2016-04-12 25 views
5

Tôi đang cố gắng tạo một thành phần nơi bạn có thể vượt qua đường ống nào sẽ được sử dụng cho danh sách bên trong thành phần. Từ những gì tôi có thể tìm bằng cách kiểm tra và nhìn xung quanh cho câu trả lời giải pháp duy nhất xuất hiện để tạo ra một cái gì đó như:Ống động trong Angular 2

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

my-component mẫu:

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

Mà sau đó bản đồ myFilter để logic ống đúng và chạy nó , nhưng điều này có vẻ hơi bẩn và không tối ưu.

Tôi nghĩ rằng họ sẽ đưa ra một giải pháp tốt hơn cho vấn đề này kể từ Angular 1, nơi bạn cũng sẽ làm điều gì đó dọc theo những dòng này.

Có cách nào tốt hơn để làm điều này trong Angular 2 không?

+0

là getpipe bộ lọc tùy chỉnh của bạn? –

Trả lời

3

Rất tiếc, tôi không nghĩ vậy. Nó giống như trong angular1, nơi bạn có một hàm trả về một chuỗi cho Pipe động mà bạn muốn.

Nhìn vào tài liệu chính xác như cách chúng hiển thị nó.

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> 
` 

Sau đó, trong bộ điều khiển:

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

Alas, nó có thể tồi tệ hơn! :)

1

Tôi đã xoay xở để làm việc gì đó, nó hơi bẩn và tà ác (với eval) nhưng nó thực sự là mánh khóe đối với tôi. Trong trường hợp của tôi, tôi có một thành phần bảng với các kiểu dữ liệu khác nhau trong mỗi hàng (ví dụ: tiêu đề, url, ngày tháng, trạng thái). Trong cơ sở dữ liệu của tôi, trạng thái được đánh dấu là 1enabled hoặc 0 cho disabled. Tất nhiên, nó là thích hợp hơn để được hiển thị kích hoạt/vô hiệu hóa cho người dùng của tôi. Ngoài ra, cột tiêu đề của tôi là đa ngôn ngữ, làm cho nó trở thành đối tượng có một hoặc là en hoặc id làm khóa của nó.

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

Lý tưởng nhất, tôi cần 2 ống khác nhau để chuyển đổi dữ liệu để hiển thị cho người dùng ứng dụng của tôi. Một cái gì đó như translateTitlegetStatus sẽ hoạt động tốt. Hãy gọi đường ống của phụ huynh dynamicPipe.

/// 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] 
    } 
} 

Tôi có thể sẽ rất ghét sử dụng eval. Hy vọng nó giúp!

Cập nhật: khi bạn có thể cần 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> 

Sẽ trả lại:

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

Cách dễ nhất để giải quyết vấn đề này sẽ không sử dụng các đường ống trong các mẫu HTML, nhưng thay vào đó, tiêm các đường ống vào một constructor của thành phần (sử dụng DI), sau đó áp dụng các biến đổi chức năng. Điều này hoạt động khá tốt với bản đồ Quan sát hoặc các luồng rxj tương tự.

+0

Đề nghị tốt, tuy nhiên nó vẫn sẽ yêu cầu một dịch vụ bao bọc nếu nó được sử dụng theo cách tôi muốn. – Chrillewoodz

2

Xây dựng về câu trả lời của borislemke, đây là một giải pháp mà không cần eval() và mà tôi tìm thấy khá sạch:

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 = []; 
} 
Các vấn đề liên quan