2016-07-24 45 views
14

我正在使用Angular2和Typscript。我有一個枚舉:如何使用ngFor作爲字符串數組遍歷Typescript Enum

export enum Role { 
    ServiceAdmin, CompanyAdmin, Foreman, AgentForeman, 
    CrewMember, AgentCrewMember, Customer 
} 

我想使用* ngFor遍歷枚舉。做這個的最好方式是什麼?我必須創建一個管道嗎?還是有更簡單的方法?

回答

20

枚舉只是一個對象。

你枚舉寫這樣的事情在JavaScript:

{ 
    0: "ServiceAdmin", 
    1: "CompanyAdmin", 
    2: "Foreman", 
    3: "AgentForeman", 
    4: "CrewMember", 
    5: "AgentCrewMember", 
    6: "Customer", 
    ServiceAdmin: 0, 
    CompanyAdmin: 1, 
    Foreman: 2, 
    AgentForeman: 3, 
    CrewMember: 4, 
    AgentCrewMember: 5, 
    Customer: 6 
} 

所以,你可以重複它這種方式(plnkr):

@Component({ 
    ... 
    template: ` 
    <div *ngFor="let item of keys()"> 
     {{ item }} 
    </div> 
    ` 
}) 
export class YourComponent { 
    role = Role; 
    keys() : Array<string> { 
     var keys = Object.keys(this.role); 
     return keys.slice(keys.length/2); 
    } 
} 

或者會更好地創建自定義管

@Pipe({ 
    name: 'enumToArray' 
}) 
export class EnumToArrayPipe implements PipeTransform { 
    transform(data: Object) { 
    const keys = Object.keys(data); 
    return keys.slice(keys.length/2); 
    } 
} 

Example

+0

如果包含負值,這不太好。 btw:plnkr不再工作了。 –

+0

@ MA-Maddin更新解鎖器 – yurzui

9

模板的範圍是組件實例。如果你想這個範圍之外的東西訪問你需要使它可以從withing您的組件實例:

@Pipe({name: 'keys'}) 
export class KeysPipe implements PipeTransform { 
    transform(value, args:string[]) : any { 
    let keys = []; 
    for (var enumMember in value) { 
     var isValueProperty = parseInt(enumMember, 10) >= 0 
     if (isValueProperty) { 
     keys.push({key: enumMember, value: value[enumMember]}); 
     // Uncomment if you want log 
     // console.log("enum member: ", value[enumMember]); 
     } 
    } 
    return keys; 
    } 
} 

@Component({ 
    ... 
    pipes: [KeysPipe], 
    template: `<div *ngFor="let item of roles | keys">{{item}}</div>` 
}) 
class MyComponent { 
    roles = Role; 
} 

又見https://stackoverflow.com/a/35750252/217408

+0

感謝您的幫助。我只是試過這個,但得到錯誤「NgFor只支持綁定到陣列等Iterables。」所以看起來我可以創建一個管道將角色轉換爲枚舉或字符串數​​組。但在我看來,我應該能夠以某種方式在本地做到這一點。 –

+0

對不起,忘了管道。更新了我的答案。 –

+1

謝謝!比Array更好的解決方案:-) –

3

經過進一步的研究和其他答案的檢討,我現在就可以制定一個回答我的問題。我認爲它不可能只使用* ngFor迭代枚舉而不在組件中提供一些代碼支持。代碼支持可以由將Enum轉換成某種數組的構造函數代碼組成,或者我們可以創建一個類似的自定義管道。

6

我需要做同樣的事情,也許這就是你想要的。
更多DRY,它也可以與module一起使用。

export enum Role { 
    ServiceAdmin, CompanyAdmin, Foreman, AgentForeman, 
    CrewMember, AgentCrewMember, Customer 
} 

export namespace Role { 

    export function keys(): Array<string>{ 
    var keys = Object.keys(Role); 
    return keys.slice(keys.length/2, keys.length-1); 
    } 
} 

切片前的對象輸出

{ 
    "1", 
    "2", 
    "3", 
    "4", 
    "5", 
    "6", 
    "7", 
    "ServiceAdmin", 
    "CompanyAdmin", 
    "Foreman", 
    "AgentForeman", 
    "CrewMember", 
    "AgentCrewMember", 
    "Customer", 
    "keys" 
} 

打字稿合併兩個聲明因此keys.lenght-1

ngFor

<div *ngFor="let role of Roles.keys()">{{ role }}</div> 

詳細信息:基於
Typescript's Declaration merging


TypeScript: Add functions to an Enum https://basarat.gitbooks.io/typescript/content/docs/enums.html(在枚舉結束章。)

+1

並獲取值,你會做相反的事情:let values = Object.keys(ApplicationMode);返回values.slice(0,values.length/2);謝謝你的想法。 – AFD

+0

切片之前沒有「keys」項,因此您不需要'keys.lenght-1' – KlsLondon