Angular 6:使用服务获取本地json数据

时间:2018-11-06 15:11:21

标签: json angular

我有一个包含电影列表的movies.json,我想创建一个MoviesServices来获取所需的数据。

我的电影服务:

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

@Injectable({
  providedIn: 'root'
})

export class MoviesService {

  movies: string[];

  constructor(private httpService: HttpClient) {
    this.getMovies();
  }

  getMovies() {
    this.httpService.get('../../assets/movies.json').subscribe(
      data => {
        this.movies = data as string[];
        console.log(this.movies); // My objects array
      },
      (err: HttpErrorResponse) => {
        console.log(err.message);
      }
    );
    console.log(this.movies); // Undefined
  }

}

首先,我不知道第一个 console.log()为何起作用,第二个为什么不起作用,你能告诉我为什么吗?

这是我需要获取数据的组件:

import { Component, OnInit } from '@angular/core';
import { MoviesService } from '../services/movies/movies.service';

@Component({
  selector: 'app-movies',
  templateUrl: './movies.component.html',
  styleUrls: ['./movies.component.css']
})

export class MoviesComponent implements OnInit {
  title = 'films-synopsys';
  movies;

  constructor(private myService: MoviesService) {}

  ngOnInit() {
    console.log(this.myService.movies); // Undefined
  }
}

当然这是行不通的。你能告诉我怎么办吗?我是新手,有角

3 个答案:

答案 0 :(得分:3)

因此,基本上,您需要从服务中返回Observable,然后从组件中返回subscribe。然后,您可以将response分配给Component属性movies

尝试一下:

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

@Injectable()
export class MoviesService {

  constructor(private httpService: HttpClient) { }

  getMovies() {
    return this.httpService.get('../../assets/movies.json');
  }

}

在您的组件中:

import { Component } from '@angular/core';
import { MoviesService } from './movies.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  title = 'films-synopsys';
  movies;

  constructor(private myService: MoviesService) {}

  ngOnInit() {
    this.myService.getMovies()
      .subscribe(res => this.movies = res);
  }
}

这是您推荐的Sample StackBlitz

答案 1 :(得分:1)

第一个控制台日志起作用的原因是因为您正在观察对象的订阅中进行操作。订阅具有三种状态,NextErrorComplete,因此,当您第一次进行控制台日志记录时,在订阅next状态内,您将获得从事件流。

在您的组件中之所以不起作用,是因为可观察对象是惰性的,并且您需要通过首先调用this.myService.getMovies()来进行订阅来初始化数据。

一种更好的方法是在HTML模板中传递可观察对象并使用async管道。

答案 2 :(得分:1)

更改方法以返回可订阅的Observable:

import { Observable } from 'rxjs/Observable';
...
getMovies(): Observable<string []> {
    this.httpService.get('../../assets/movies.json').subscribe(
      data => {
        this.movies = data as string[];
        return this.movies;
      },
      (err: HttpErrorResponse) => {
        console.log(err.message);
      }
    );
  }

在您的呼叫代码中:

import { Subscription } from 'rxjs/Subscription';

this.myService.getMovies().subscribe(movies => {
  console.log(movies); // My objects array
}