【问题标题】:Load json data in service and return it to component在服务中加载json数据并返回给组件
【发布时间】:2018-02-27 16:57:19
【问题描述】:

我有一个带有控制器和模板的组件。我正在使用服务从json 文件加载数据并将其返回给我的组件。返回的数据应该在组件的模板中循环。目前,我服务中的console.log() 向我显示了正确的数据,因此它从json 文件中加载了所有内容。我的组件中的console.log() 是错误的。我知道,有几个问题的答案,但他们没有帮助我。异步加载有问题吗?有任何想法吗?我还在问题底部附上了控制台错误。

test.json

[
  {
    "Id": 1,
    "Name": "Item 1"
  },
  {
    "Id": 2,
    "Name": "Item 2"
  },
  {
    "Id": 3,
    "Name": "Item 3"
  }
]

test.component.ts

import { Component, OnInit } from "@angular/core";
import { NavigationService } from "../../../services/navigation.service";

export type NavigationListModel = { Id: number; Name: string };

@Component({
  selector: "test",
  templateUrl: "./test.component.html",
  styleUrls: ["./test.component.scss"]
})
export class TestComponent implements OnInit {
  navigationList: Array<NavigationListModel>;

  constructor(private _navService: NavigationService) {
    this.navigationList = this._navService.loadNavigationList();
    console.log(this.navigationList);
  }

  ngOnInit() {}
}

test.service.ts

import { Injectable } from "@angular/core";
import { Http, Response } from "@angular/http";
import 'rxjs/add/operator/map';


@Injectable()
export class NavigationService {
  constructor(private http: Http) {
  }

  loadNavigationList() {
    return this.http
      .get("/assets/mock/test/test.json")
      .map(data => data.json() as Array<NavigationService>)
      .subscribe(data => {
        console.log(data);
        return data;
      });
  }
}

test.component.html

<div *ngFor="let item of navigationList">
  {{item.Name}}
</div>

CONSOLE 和 CONSOLE.LOG() 结果中的错误:

【问题讨论】:

  • 附带说明,您不应该在组件构造函数中进行初始化。您需要将该逻辑移至 OnInit() 生命周期挂钩。

标签: javascript html angular typescript http-get


【解决方案1】:

当您创建返回 HTTP 并且它是异步的服务时,您需要订阅调用它的那个函数。如您所见,您的控制台日志告诉您它是订阅。

试试:

this._navService.loadNavigationList().subscribe((data: any) => {
    console.log(data)
});

或者您可以重新创建您的服务,该服务将返回带有解析和错误的新 Promise,我通常更喜欢这样做

 loadNavigationList() {
    return new Promise((error, resolve) => {
     this.http
      .get("/assets/mock/test/test.json")
      .map(data => data.json() as Array<NavigationService>)
      .subscribe((data) => {
        // if api, check for errr
        if(data.code == 500) {
          error(something);
          return
        }
        resolve(data)
      });
    });
  }

你会怎么称呼它

loadNavigationList().then((data) => {

}, (err) => {

})

【讨论】:

    【解决方案2】:

    您正在遍历由于异步调用而仍未定义的 navigationList 字段(尚未收到响应)。

    要解决这个问题,你必须让你的 loadNavigationList() 方法返回一个可观察的 Array 并在模板内的异步管道的测试组件中使用它:

    test.service.ts:

    import { Injectable } from "@angular/core";
    import { Http, Response } from "@angular/http";
    import 'rxjs/add/operator/map';
    
    
    @Injectable()
    export class NavigationService {
      constructor(private http: Http) {
      }
    
      loadNavigationList() {
        return this.http
          .get("/assets/mock/test/test.json")
          .map(data => data.json() as Array<NavigationService>);
      }
    }
    

    test.component.ts:

    import { Component, OnInit } from "@angular/core";
    import { NavigationService } from "../../../services/navigation.service";
    
    export type NavigationListModel = { Id: number; Name: string };
    
    @Component({
      selector: "test",
      templateUrl: "./test.component.html",
      styleUrls: ["./test.component.scss"]
    })
    export class TestComponent implements OnInit {
      navigationListObservable$: Observable<Array<NavigationListModel>>;
    
      constructor(private _navService: NavigationService) {
        this.navigationList$ = this._navService.loadNavigationList();
      }
    
      ngOnInit() {}
    }
    

    test.component.html

    <div *ngFor="let item of  (navigationListObservable$ | async)">
          {{item.Name}}
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      相关资源
      最近更新 更多