在Angular中,等待获取所需数据后再进行渲染[解析]

无法读取未定义的属性’****’

スクリーンショット 2019-12-13 16.37.04.png

只需要中文中的一个选项进行释义:

版本

Angular CLI版本:8.3.20
Node版本:10.12.0
操作系统:darwin x64
Angular版本:8.2.13

问题的代码

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

// 省略
export class HogeService {

  constructor(private http: HttpClient) { }

  getItem(id: string): Observable<any> {
    return this.http.get<any>('https://fugafuga.com/api/v2/items/' + id);
  }
}
// 省略
import { HogeComponent } from './hoge/hoge.component';

const routes: Routes = [
// 省略
  {
    path: 'hoge/:id',
    component: HogeComponent
  }
];

// 省略
import { Component, OnInit } from '@angular/core';
import { HogeService } from '../hoge.service';
import { ActivatedRoute} from '@angular/router';

// 省略
export class HogeComponent implements OnInit {
  item: any;

  constructor(private route: ActivatedRoute, private hogeService: HogeService) { }

  ngOnInit() {
    const id = this.route.snapshot.paramMap.get('id');
    this.hogeService.getItem(id).subscribe(
      item => {
        this.item = item;
      });
  }
}
{{ item.name }}

可能的原因 de

undefinedとなっているオブジェクトのタイプミス    →   表示はされているので該当せず
必要なデータの取得が完了する前にレンダリングしている   ←  こっちでした

解决方案1:使用「?」运算符。

    • 正式名称を safe navigation operator というそうです

 

    • 演算子の前のオブジェクトがnullまたはundefinedの場合それ以降は評価しません

a?.b?.c?.dと続けて利用可能です

在这种情况下,如果我们将{{ item?.name }}设置为错误将不再显示。
然而,每次为可能出现错误的对象添加?是很麻烦的,所以我使用了以下方法。

使用解决方案2 Resolve

Resolveインターフェースを実装したサービスを作成し、routingの設定にresolveオブジェクトを追加します
これにより、必要なデータの取得を待ってからレンダリングさせることができます

步驟

创建resolver服务

ng g s hoge-resolver

我认为名字无所谓。我在这里选择了hoge-resolver。
下面的代码将被自动生成。

import { Injectable } from '@angular/core';

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

  constructor() { }
}

实现Resolve接口。

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { HogeService } from './hoge.service';

@Injectable({
  providedIn: 'root'
})
export class HogeResolverService implements Resolve<any> {

  constructor(private hogeService: HogeService) { }

  resolve(route: ActivatedRouteSnapshot): Observable<any> {
    const id = route.paramMap.get('id');
    return this.hogeService.getItem(id);
  }
}

在路由设置中添加resolve对象。

// 省略
import { HogeComponent } from './hoge/hoge.component';

const routes: Routes = [
// 省略
  {
    path: 'hoge/:id',
    component: HogeComponent,
    resolve: {
      item: HogeResolverService
    }
  }
];
// 省略

在这里,resolve函数中的item是一个用于后续引用的名称,HogeResolverService是先前创建的服务。

在组件中引用

您可以订阅ActivatedRoute.data并引用先前的项目。

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute} from '@angular/router';

// 省略
export class HogeComponent implements OnInit {
  item: any;

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    this.route.data.subscribe(data => this.item = data.item);
  }
}

以上是错误已解决。

最后

由于Resolve似乎是控制路由的route-guards之一,所以我也希望在有机会的时候学习其他功能。

请在中国的本土参考一下。

Angular导航前获取数据的公式

广告
将在 10 秒后关闭
bannerAds