【问题标题】:Angular5: ngOnInit is only invoked once on routingAngular5:ngOnInit 只在路由上调用一次
【发布时间】:2018-10-23 05:32:09
【问题描述】:

我有一个基本的应用程序,我可以在其中使用数据服务从 Firestore 中获取数据。我有几个页面(组件)、球队、球员、统计数据......

例如我的团队组件:

import { Component, OnInit } from '@angular/core';
import { TeamsService } from '../../services/teams.service';
import { Team } from '../../models/team';
import {Observable} from 'rxjs/Observable';


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


  public teams: Team[];
  editState: boolean = false;
  teamToEdit: Team;
  showAdd: boolean = false;
  showSelect: boolean = false;
  selectedTeam: Observable<Team>;

  constructor(public teamsService: TeamsService) {
  }

  ngOnInit() {

          this.teamsService.getTeams().subscribe(teams => {
            this.teams = teams;
            console.log('ngOnInit invoked');
          });
        }


  deleteTeam(event, team) {
    const response = confirm('are you sure you want to delete?');
    if (response) {
      this.teamsService.deleteTeam(team);
    }
    return;
  }

  editTeam(event, team) {
    this.editState = !this.editState;
    this.teamToEdit = team;
  }

  updateTeam(team) {
    this.teamsService.updateTeam(team);
    this.teamToEdit = null;
    this.editState = false;
  }

  showAddForm() {
      this.showAdd = !this.showAdd;
    }

  getTeam(event, team) {
    this.showSelect = !this.showSelect;
    this.selectedTeam = this.teamsService.getTeamById(team.id);
  }
}

在 ngOnInit 中,我将数据加载到局部变量中,但是一旦我导航到另一个页面然后返回,数据就消失了。我确实需要刷新页面以重新加载数据。

我应该如何解决这个问题?

【问题讨论】:

  • 该生命周期钩子仅在组件第一次初始化时触发,详情见angular.io/guide/lifecycle-hooks
  • 将 console.log 放在订阅之外,看看它是否真的没有被调用,或者它是否是服务的问题。
  • 创建共享服务并注入ngmoduleproviders属性,在此导入服务到您的component之后,您无需刷新整个页面即可加载数据。
  • 你需要创建一个全局数据服务才能得到上述结果。

标签: angular angular5 ngoninit


【解决方案1】:

创建一个解析器保护并在 TeamsComponent 的路由配置中使用它。此外,创建一个将进行数据检索并将其注入解析器的服务。该服务可以在用户每次导航到该路由时发出新的数据请求,也可以缓存数据并在每次后续访问该路由时将它们提供给您的 TeamComponent。

看看这个示例应用程序,它说明了解析器保护的一般用法:https://github.com/Farata/angulartypescript/tree/master/code-samples/chapter4/router-advanced-samples/src/app/resolver

但如果你想实现一个带有缓存的可注入服务,请看一下 data.resolver2.ts 和 data.service.ts 中的代码。

【讨论】:

  • 感谢您的解决方案,但您能否详细说明具体步骤?我已经有一项服务可以从 Firestore 中获取数据` `
  • 在我的 DataService 中,我将一个 48MB 的大文件读入一个变量 myData,它用作缓存 github.com/Farata/angulartypescript/blob/master/code-samples/…。当用户第一次导航到我的 DataComponent 时,服务将读取这个大文件。但是如果我导航到另一条路线然后返回 DataComponent,服务中的 if 语句将看到 myData 不为假,并且将返回其数据而不再次读取文件。
  • 如果我理解你缓存数据并检查它是否仍然存在。如果是,请不要再次加载它。从我看到我的问题是不同的。我在我的组件中注入了数据服务,我在 this.teams 中缓存了数据,但是当我导航到另一个页面并返回时,数据就消失了。试图用其他生命周期钩子来解决它,但它们似乎都只在创建时被调用一次。我在这里错过了什么吗?
  • 是的,您错过了这样一个事实,即我将数据缓存在单例服务中,该服务在组件创建和销毁后仍然存在。
猜你喜欢
  • 2018-08-08
  • 2018-07-21
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-30
  • 2021-06-12
  • 2017-10-04
相关资源
最近更新 更多