访问键和使用* ngFor的对象的值
如何在angular2中获取对象的Key and Value
的时候感到困惑,而用于迭代对象的时候会感到困惑。 我知道在角1.x有语法
ng-repeat="(key, value) in demo"
但在角2我不知道我累了,但没有成功。 我已经尝试了下面的代码,但没有运行,请告诉我在哪里做错了。
<ul> <li *ngFor='#key of demo'>{{key}}</li> </ul> demo = { 'key1': [{'key11':'value11'}, {'key12':'value12'}], 'key2': [{'key21':'value21'}, {'key22':'value22'}], }
这里是plnkr我曾尝试过的相同: http ://plnkr.co/edit/mIj619FncOpfdwrR0KeG?p=preview
我想使用* ngFor动态获取key1
和key2
。 如何得到它? 我搜查了很多使用管道发现的想法,但如何使用我不知道。 有没有在angular2做同样的任何inbuild管道?
您可以创建一个自定义管道来返回每个元素的键列表。 类似的东西:
import { PipeTransform, Pipe } from '@angular/core'; @Pipe({name: 'keys'}) export class KeysPipe implements PipeTransform { transform(value, args:string[]) : any { let keys = []; for (let key in value) { keys.push(key); } return keys; } }
并像这样使用它:
<tr *ngFor="#c of content"> <td *ngFor="#key of c | keys">{{key}}: {{c[key]}}</td> </tr>
编辑
您也可以返回包含键和值的条目:
@Pipe({name: 'keys'}) export class KeysPipe implements PipeTransform { transform(value, args:string[]) : any { let keys = []; for (let key in value) { keys.push({key: key, value: value[key]}); } return keys; } }
并像这样使用它:
<span *ngFor="#entry of content | keys"> Key: {{entry.key}}, value: {{entry.value}} </span>
在模板中可以访问Object.keys
,并在*ngFor
使用它。
@Component({ selector: 'app-myview', template: `<div *ngFor="let key of objectKeys(items)">{{key + ' : ' + items[key]}}</div>` }) export class MyComponent { objectKeys = Object.keys; items = { keyOne: 'value 1', keyTwo: 'value 2', keyThree: 'value 3' }; constructor(){} }
用例子来阐述@ Thierry的回答。
没有内置的管道或方法从* ngFor循环获取key and value
。 所以我们必须为此创建自定义管道。 正如thierry所说,这是代码的答案。
** Pipe类实现了PipeTransform接口的transform方法,该方法接受一个输入值和一个可选的参数字符串数组,并返回转换后的值。
**变换方法对于管道是必不可少的。 PipeTransform接口定义了该方法并指导了工具和编译器。 这是可选的; 无论角度如何查找并执行变换方法。 欲了解更多信息关于管这里参考
import {Component, Pipe, PipeTransform} from 'angular2/core'; import {CORE_DIRECTIVES, NgClass, FORM_DIRECTIVES, Control, ControlGroup, FormBuilder, Validators} from 'angular2/common'; @Component({ selector: 'my-app', templateUrl: 'mytemplate.html', directives: [CORE_DIRECTIVES, FORM_DIRECTIVES], pipes: [KeysPipe] }) export class AppComponent { demo = { 'key1': 'ANGULAR 2', 'key2': 'Pardeep', 'key3': 'Jain', } } @Pipe({name: 'keys'}) export class KeysPipe implements PipeTransform { transform(value, args:string[]) : any { let keys = []; for (let key in value) { keys.push({key: key, value: value[key]}); } return keys; } }
和HTML部分是:
<ul> <li *ngFor='#key of demo | keys'> Key: {{key.key}}, value: {{key.value}} </li> </ul>
工作Plnkr http://plnkr.co/edit/50LlK0k6OnMnkc2kNHM2?p=preview
更新到RC
如user6123723建议(谢谢)在这里的评论是更新。
<ul> <li *ngFor='let key of demo | keys'> Key: {{key.key}}, value: {{key.value}} </li> </ul>
@Marton 对于接受的答案有一个重要的反对意见,理由是管道在每次变更检测时创建一个新的收集。 我会创建一个HtmlService,它提供了视图可以使用的一系列实用函数:
@Component({ selector: 'app-myview', template: `<div *ngFor="let i of html.keys(items)">{{i + ' : ' + items[i]}}</div>` }) export class MyComponent { items = {keyOne: 'value 1', keyTwo: 'value 2', keyThree: 'value 3'}; constructor(private html: HtmlService){} } @Injectable() export class HtmlService { keys(object: {}) { return Object.keys(object); } // ... other useful methods not available inside html, like isObject(), isArray(), findInArray(), you'll think of others... }
如果你已经使用Lodash,你可以做这个简单的方法,包括键和值:
<ul> <li *ngFor='key of _.keys(demo)'>{{key}}: demo[key]</li> </ul>
在打字稿文件中,包括:
import * as _ from 'lodash';
并在导出的组件中包括:
_: any = _;
感谢管道,但我不得不做一些改变,然后我可以在角度2 RC5中使用它。 更改了管道导入行,并添加了任何类型的键数组初始化。
import {Pipe, PipeTransform} from '@angular/core'; @Pipe({name: 'keys'}) export class KeysPipe implements PipeTransform { transform(value) { let keys:any = []; for (let key in value) { keys.push( {key: key, value: value[key]} ); } return keys; } }
有一个真正好的图书馆,在其他好的管道之间做到这一点。 这就是所谓的ngx管道 。
例如,键管道返回对象的键,值管道返回对象的值:
键管道
<div *ngFor="let key of {foo: 1, bar: 2} | keys">{{key}}</div> <!-- Output: 'foo' and 'bar -->
值管道
<div *ngFor="let value of {foo: 1, bar: 2} | values">{{value}}</div> <!-- Output: 1 and 2 -->
不需要创建自己的定制管道:)
这是简单的解决方案
你可以使用typecript迭代器来做到这一点
import {Component} from 'angular2/core'; declare var Symbol; @Component({ selector: 'my-app', template:`<div> <h4>Iterating an Object using Typescript Symbol</h4><br> Object is : <p>{{obj | json}}</p> </div> ============================<br> Iterated object params are: <div *ngFor="#o of obj"> {{o}} </div> ` }) export class AppComponent { public obj: any = { "type1": ["A1", "A2", "A3","A4"], "type2": ["B1"], "type3": ["C1"], "type4": ["D1","D2"] }; constructor() { this.obj[Symbol.iterator] = () => { let i =0; return { next: () => { i++; return { done: i > 4?true:false, value: this.obj['type'+i] } } } }; } }
这里没有任何答案为我开箱,这是什么为我工作:
用内容创建pipes/keys.ts
:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'keys'}) export class KeysPipe implements PipeTransform { transform(value:any, args:string[]): any { let keys:any[] = []; for (let key in value) { keys.push({key: key, value: value[key]}); } return keys; } }
添加到app.module.ts
(您的主要模块):
import { KeysPipe } from './pipes/keys';
然后添加到你的模块声明数组像这样:
@NgModule({ declarations: [ KeysPipe ] }) export class AppModule {}
然后在你的视图模板中,你可以使用这样的东西:
<option *ngFor="let entry of (myData | keys)" value="{{ entry.key }}">{{ entry.value }}</option>
如果您想要阅读更多内容,请点击这里查看。
我认为Object.keys是解决这个问题的最好方法。 对于任何遇到这个问题的人来说,试图找出Object.keys为什么给他们['0','1']而不是['key1','key2'],这是一个警示故事 – 要小心“ of“和”in“:
我已经在使用Object.keys,类似这样的:
interface demo { key: string; value: string; } createDemo(mydemo: any): Array<demo> { const tempdemo: Array<demo> = []; // Caution: use "of" and not "in" for (const key of Object.keys(mydemo)) { tempdemo.push( { key: key, value: mydemo[key]} ); } return tempdemo; }
但是,而不是
for (const key OF Object.keys(mydemo)) {
我无意中写道
for (const key IN Object.keys(mydemo)) {
哪个“工作”完美没有任何错误,并返回
[{key: '0', value: undefined}, {key: '1', value: undefined}]
这花了我大约2个小时的谷歌搜索和诅咒..
(拍额头)
另一种方法是创建NgForIn
指令,将使用像
<div *ngFor="let key in obj"> <b>{{ key }}</b>: {{ obj[key] }} </div>
Plunker例子
ngforin.directive.ts
@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); } } }
你必须这样做,现在我知道不是很有效,因为你不想转换你从firebase接收到的对象。
this.af.database.list('/data/' + this.base64Email).subscribe(years => { years.forEach(year => { var localYears = []; Object.keys(year).forEach(month => { localYears.push(year[month]) }); year.months = localYears; }) this.years = years; });