Angular / Firebase - 如何在对象上使用* ngFor

时间:2017-08-25 11:03:28

标签: angular firebase firebase-realtime-database

我正在使用

  • 火力地堡

我有什么

  • 显示'问题'

  • 的详细信息的组件
  • 在问题中,我有另一个名为' images'

  • 的节点
  • 在图片节点内,我还有其他属性,例如' image_title'

我想要实现的目标

  • 我的问题组件可以显示与问题相关的所有数据

  • 但是,图像节点

  • 下可能会出现多个图像问题
  • 我想循环遍历图片节点并显示所有' image_title'特性

错误 我通过以下代码收到以下错误:

  

错误错误:无法找到不同的支持对象' [object Object]'类型'对象'。 NgFor仅支持绑定到Iterables,例如Arrays。

问题

  • 这怎么可能?

问题列表解析器

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
        return Observable.create(observer => {

            this.authService.user
                .first()
                .subscribe(user => {

                    const projectId = route.params['projectId'];
                    const issueId = route.params['issueId'];

                    this.database.object(`/issue/${projectId}/${issueId}`)
                        .first()
                        .subscribe(issue => {
                            observer.next(issue);
                            observer.complete();
                        });
                });
        });
    }

问题组件 imagesToDisplay是:

&#39; imagesToDisplay:FirebaseListObservable;&#39;

    this.activatedRoute.data
      .subscribe((
        data: { issueData: any, issueImageData: any }) => {
        this.issueToDisplay = data.issueData;
        this.imagesToDisplay =  data.issueData.images;
        console.log(this.imagesToDisplay);
      });

问题组件HTML

我在HTML中发表评论,试图循环播放图片。

<ul class="vs__details__ul">

  <li class="vs__details__li" *ngIf="issueToDisplay.issue_title">
    <div class="vs__label"> Issue Title </div>
    <div class="vs__data"> {{ issueToDisplay.issue_title }} </div>
  </li>

  <li class="vs__details__li" *ngIf="issueToDisplay.issue_comments">
    <div class="vs__label"> Issue Comments </div>
    <div class="vs__data"> {{ issueToDisplay.issue_comments }} </div>
  </li>

  <li class="vs__details__li">
    <div class="vs__label"> Images </div>
    <!-- LOOP THROUGH IMAGES HERE -->
    <div class="issue__images" *ngFor="let image of imagesToDisplay">

    <div class="vs__data"> {{ image.image_title }}</div>
    </div>
  </li>

</ul>

来自Firebase的JSON结构

enter image description here

控制台 - (来自组件中的console.log)

enter image description here

2 个答案:

答案 0 :(得分:2)

创建自定义管道keys,以获取keys

Object列表
// pipes.ts
import { Pipe, PipeTransform } from '@angular/core';


@Pipe({ name: 'keys' })
export class KeysPipe implements PipeTransform {
    transform(value, args: string[]): any {
        if(value instanceof Object) return Object.keys(value);
        else return [];
    }
}

app.module.ts

中添加新的自定义管道
// app.module.ts
import { KeysPipe } from './pipes.ts;

@NgModule({
 declarations: [ KeysPipe ]

并使用它来迭代Object

中的*ngFor
<div *ngFor="let img of images | keys">
   <p>{{x[img]['title']}}</p>
</div>

图片对象:

images = {
   'img1': {'title': 'Title1'},
   'img2': {'title': 'Title2'},
   'img3': {'title': 'Title3'},
   'img4': {'title': 'Title4'}
}

答案 1 :(得分:2)

问题是您需要将图像(这是一个对象文字)转换为可迭代的,以便imagesToDisplay识别它。您可以将所有图像添加到数组中,然后再将其传递给const images = []; for (const image of Object.keys(data.issueData.images)) { images.push(data.issueData.images[image]); } this.imagesToDisplay = images;

interface Image {
  image_title: string;
}
// ...

function getIterableImages(images: any): Image[] {
  const arrayImages = [];

  // returns empty array if input is not defined
  if (images == undefined) return arrayImages;

  // returns an array of first level elements inside of object
  for (const key of Object.keys(images)) {
    if (images[key] != undefined) {
      arrayImages.push(images[key]);
    }
  }
  return arrayImages;
}
// ...

this.activatedRoute.data
      .subscribe((
        data: { issueData: any, issueImageData: any }) => {
        this.issueToDisplay = data.issueData;
        this.imagesToDisplay = getIterableImages(data.issueData.images);
        console.log(this.imagesToDisplay);
      });

为你做一个功能:

$pdo