首页 > 解决方案 > 无法迭代 Angular 6 中的本地对象数组?

问题描述

我是 Angular 6 的新手,我正在尝试迭代一组对象,但它什么也没产生。网上的人都在谈论订阅 observable,如果这是问题,我不知道该怎么做。

这是我的组件:

import { Component, OnInit } from '@angular/core';
import { Topic } from '../topic';
import { TopicFetcherService } from '../topic-fetcher.service'

@Component({
  selector: 'app-topics',
  templateUrl: './topics.component.html',
  styleUrls: ['./topics.component.css']
})
export class TopicsComponent implements OnInit {

  constructor( private topicFetcher: TopicFetcherService) { }

  topics: Topic[];

  ngOnInit() { 

    // this grabs my topics from my http service
    this.processTopics(this.topicFetcher.getData()); 

  }

  processTopics(rawTopics: Topic[]) {

    console.log(rawTopics); // this works 

    rawTopics.forEach(topic => {
      console.log(topic.id); // this does not work ? 
    });

  }

}

我不明白为什么 console.log(rawTopics) 有效,但如果你尝试迭代它,你必须参与 observables。这似乎有点沉重。

编辑:

这是我的主题获取服务。它目前只是资产中的 .get 的 .json 文件:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Topic } from './topic';

@Injectable({
  providedIn: 'root'
})
export class TopicFetcherService {

  constructor(private http: HttpClient) { }

  topics: Topic[];

  getData(): Topic[] {

    this.topics = [];
    let index = 1;

    this.http.get('assets/topics.json')
    .subscribe(data => {     
      for (const key in data) {
        let topic = new Topic();
        topic.id = index;
        topic.title = data[key].topic;
        topic.description = data[key].narrative;
        topic.type = data[key].type;
        topic.dataset = data[key].dataset;
        this.topics.push(topic);
        index++;
      }
     });

     return this.topics;

  }

}

标签: angularangular6

解决方案


如果getData()返回一个 observable 类型Observable<Topic[]>,你需要订阅(和取消订阅)它。首先导入 Observable

import { Observable } from 'rxjs'

在你的组件类中

ngOnInit() {
  this.processTopics(this.topicFetcher.getData()); 
}

processTopics(rawTopics$: Ovservable<Topic[]>) {
  rawTopics$.subscribe((rawTopics) => {
    console.log(rawTopics); // this works 

    rawTopics.forEach(topic => {
      console.log(topic.id); // this does not work ? 
    });
  });
}

在最后标记可观察对象是一个很好的做法$,但这主要是基于意见的。

退订

OnDestroy要取消订阅,引入组件生命周期钩子并在其中取消订阅是有意义的。

import { OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

将成员添加到您的组件类,例如命名subscription: Subscription。然后将订阅分配processTopics给该变量。

this.subscription = rawTopics$.subscribe(...)

告诉组件类实现 ondestroy 生命周期钩子。

export class TopicsComponent implements OnInit, OnDestroy {}

最后创建钩子函数

ngOnDestory() {
  if (this.subscription) {
    this.subscription.unsubscribe();
  }
}

编辑

将您的服务更改为以下代码段(当然包含您的所有对象属性,而不是......)。不要订阅服务本身,而是将其http.get作为可观察对象返回并订阅您的组件。

getData(): Observable<Topic[]> {
  return this.http.get<Topic[]>('assets/topics.json').pipe(
    map(data => {
      data.map((entry, index) => {
        const topic = {
          id: index,
          title: entry.topic
          ...
        }
        return topic;
      });
    })
  );
}

请求还有http.get一个优点,即当 observable 接收到一个值时它们也会完成,这意味着您不必取消订阅它们。但是当你有太多不需要的订阅时,它确实会诅咒你的应用程序的性能问题。


推荐阅读