Angular 6/7 从 API 返回到先前查看的路线时获取数据

Angular 6/7 Getting Data from API When Returning to Previously Viewed Route

我是 angular 的新手,遇到了一些麻烦。我想将用户定向到一个数据输入页面,其中许多字段已经通过 api 调用数据库,按记录 ID 填充。然后用户将编辑其中一些字段,保存数据,然后继续。这一切都很好。问题是,如果用户转到另一个页面并执行其他操作,然后导航回到他们输入初始数据的相同 URL,页面上显示的数据就是最初获取的数据,而不是发布的数据。我设置了一个路由器和一个解析器来延迟加载页面,直到从 api 获取所有数据,但 api 似乎只被调用一次,而不是每次页面都被调用已加载。

我的解析器:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<ProjectVM> {
    let id = route.paramMap.get('id');
    return this.apiService.getProject(id).pipe(
        take(1),
        map(projectVM => {
            if (projectVM) {
                return projectVM;
            } else {
                this.router.navigate(['/projects']);
                return null;
            }
        }))
}

我的组件:

ngOnInit(): void {
    this.route.data.subscribe((data: { projectVM: ProjectVM }) => {
        this.projectVM = data.projectVM;
    });
}

路由模块:

const routes: Routes = [
    { path: '', redirectTo: '/projects', pathMatch: 'full', runGuardsAndResolvers: 'always' },
    { path: 'projects', component: MyProjectsComponent },
    { path: 'project/:id', component: ProjectOverviewComponent, runGuardsAndResolvers: 'always', resolve: { projectVM: ProjectResolver } },
];

@NgModule({
    imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})],
    exports: [RouterModule],
    providers: [
        { provide: APP_BASE_HREF, useValue: '/' },
        ProjectResolver,
        LeaseResolver,
        ProjectSearchResolver,
        LeaseSearchResolver
                ]  
})
export class AppRoutingModule { }

数据很好地发布到数据库,但路由器似乎不想为每个 ID 多次调用数据库。

你能在 stackblitz 中展示一下吗?顺便说一句,ngOnInit 仅在组件初始化期间被调用。因此,如果您在同一组件上,则不会调用 ngOnInit。

我发现了问题。 Angular 工作正常。问题来自 API 正在调用的 ASP.NET MVC 项目。 .NET 似乎默认缓存操作结果输出。我将 [OutputCache(NoStore = true, Duration = 0)] 作为属性添加到 Angular 调用的所有方法中,这似乎已经解决了问题。

这可能是因为您在 edit/create 请求完成之前返回。在花费 3/4 天之后,我解决了这个问题,只需在当前请求完成后导航回来即可。见下文:

解析前:

create() {
    this.deptService.addDept(this.dept).subscribe();
    //This line will execute before the above action completed.. 
    this.router.navigate(['department']);
  }

解析后:

create() {
    this.deptService.addDept(this.dept).subscribe((data) => {
        //navigate after the request has been completed!
        this.router.navigate(['department']);
      },
      (error) => {
        alert('Error occurred!');
      });
  }

或者

create() {
    this.deptService.addDept(this.dept).
      toPromise().then(x => {
        //navigate after the request has been completed!
        this.router.navigate(['department']);
      });
  }