2017-07-17 53 views
3

我正在尝试使用*ngFor而不是使用in迭代对象的属性。当我尝试这样做ngForIn可用于角度4吗?

@Controller({ 
    selector: 'sample-controller', 
    template: ` 
    <ul> 
     <li *ngFor="let i in obj"> 
     <b>{{i}}</b>: {{obj[i]}} 
     </li> 
    </ul>` 
}) 
class SampleController { 
    obj = {a: 1, b: 2} 
} 

我得到的错误信息:

不能绑定到“ngForIn”,因为它不是“礼”的已知属性。

我已经包括在@NgModule的此组件的importsFormsModuleBrowserModule

是否可以在li上使用ngForIn,如果没有,是否有一个惯用的替代方案?

+0

难道[这个问题](https://stackoverflow.com/a/34561169/2908576)? – HaveSpacesuit

+0

@HaveSpacesuit不,我想显式迭代对象的属性,而不是遍历迭代像数组。 –

+1

https://medium.com/@jsayol/having-fun-with-angular-extending-ngfor-to-support-for-in-f30c724967ed – Alex

回答

4

由于AJT_82在评论中提及您可以创建用于上述目的的特殊指令。它会根据NgForOf<T>指令:

interface NgForInChanges extends SimpleChanges { 
    ngForIn?: SimpleChange; 
    ngForOf?: SimpleChange; 
} 

@Directive({ 
    selector: '[ngFor][ngForIn]' 
}) 
export class NgForIn<T> extends NgForOf<T> implements OnChanges { 

    @Input() ngForIn: any; 

    ngOnChanges(changes: NgForInChanges): void { 
    if (changes.ngForIn) { 
     this.ngForOf = Object.keys(this.ngForIn) as Array<any>; 

     const change = changes.ngForIn; 
     const currentValue = Object.keys(change.currentValue); 
     const previousValue = change.previousValue ? 
          Object.keys(change.previousValue) : undefined; 
     changes.ngForOf = new SimpleChange(previousValue, currentValue, change.firstChange); 

     super.ngOnChanges(changes); 
    } 
    } 
} 

Plunker Example

+0

这正是我所需要的,非常感谢你! –

1

最简单的方法是使用Object.values()Object.keys()将对象转换为数组。例如,请查看this plunker

如果您想要访问密钥以及值,您可以在*ngFor中包含索引。

模板:

<ul> 
    <li *ngFor="let item of array; let index = index;"> 
    <b>{{keys[index]}}</b> value: {{item}}, index: {{index}} 
    </li> 
</ul> 

组件打字稿:

export class App { 
    obj = {a: 1, b: 2} 
    array = []; 
    keys = []; 
    constructor() { 
    } 

    ngOnInit() { 
    this.array = Object.values(this.obj); 
    this.keys = Object.keys(this.obj); 
    } 
}