Angular 2 Resolve 只工作一次

标签 angular rxjs observable resolve resolver

我正在尝试制作一个返回用户的简单 Resolve。但是,在我的应用程序中,我需要用我自己的类包装 http 组件,该类返回一个 Subject 作为可观察的。 我的 Resolver 在第一个用户链接上按预期工作,但是在 Resolve 之后单击 UserProfileComponent 中的任何用户链接时,Resolve 永远不会完成第二次。我可以看到浏览器 URL 随新 ID 发生变化, 并且 UserResolve 中的 console.log 打印,但没有任何反应。

我的路由器:

import { Routes, RouterModule } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { UserProfileComponent } from './user-profile/user-profile.component';
import { LoginComponent } from './login/login.component';
import { AuthGuard } from './_resolve/guard.auth';
import { UserResolve } from './_resolve/user.resolve';

const appRoutes: Routes = [
  { path: '', component: DashboardComponent, canActivate: [AuthGuard] },
  { path: 'user/:id', component: UserProfileComponent, canActivate: [AuthGuard], resolve: { user: UserResolve } },
  { path: 'login', component: LoginComponent },

  // otherwise redirect to home
  { path: '**', redirectTo: '' }
];

export const Routing = RouterModule.forRoot(appRoutes);

用户解析:

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { ApiService } from '../_services/api.service';
import { Observable } from 'rxjs';

import { User } from '../_models/user';

@Injectable()
export class UserResolve implements Resolve<User> {

  constructor(private apiService:ApiService) {}

  resolve(route: ActivatedRouteSnapshot):Observable<User> {
    console.log('getting user ' + route.params['id'] + ' with resolver');
    return this.apiService.getUser(route.params['id']).first();
  }
}

API服务:

import { Injectable } from '@angular/core';
import { Http, Headers, Response, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';

import { RefreshHttpClient } from '../_injectables/refresh-http-client';
import { User } from '../_models/user';

@Injectable()
export class ApiService {

  constructor(private rfhttp:RefreshHttpClient) { }

  getUser(userId):Observable<User> {
    return this.rfhttp.get('/api/user?userId=' + userId);
  }

}

和 RefreshHttpClient“获取”方法:

...
get(url):Observable<any> {
  var sub = new Subject<any>();
  var obs = this.http.get(url, {
    headers: this.createAuthorizationHeaders()
  })
  .map(res => res.json())
  .subscribe(
    data => {
      return sub.next(data);
    },
    error => {
      if (error.status == 401 || error.status == 403) {
        this.refreshAndRetry(() => {
          this.http.get(url, {
            headers: this.createAuthorizationHeaders()
          })
          .map(res => res.json())
          .subscribe(
            data => {
              return sub.next(data);
            },
            error => {
              console.error(error);
              return null;
            });
        });
      } else {
        console.error(error);
        return null;
      }
    }
  );

  return sub.asObservable();
}
...

编辑: 添加 UserProfileComponent:

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

import { User } from '../_models/user';

@Component({
  selector: 'app-user-profile',
  templateUrl: './user-profile.component.html',
  styleUrls: ['./user-profile.component.scss']
})
export class UserProfileComponent implements OnInit {

  abstract:Boolean;
  user:User;

  constructor(
    private route:ActivatedRoute
  ) { }

  ngOnInit() {
    this.user = this.route.snapshot.data['user']['data'];
    console.log(this.user);

...

请注意,我的 API 服务器返回一个带有“data”属性的 JSON 结构,因此是 ['data']

此组件中的 ngOnInit 在除第一个之外的任何路由导航上都到达,这使我相信 Resolver Observable 永远不会完成。

最佳答案

也许问题在于您如何访问已解析的数据。

当 URL 更改时,您的组件不会重新初始化,这就是为什么如果您想根据 URL 参数在组件本身内加载数据,您应该订阅路由参数更改。

因此,当您访问已解析的数据时,您可能还应该考虑到它可以在不重新初始化组件的情况下发生变化。

编辑: 从 UserProfileComponent 代码可以看出,我的假设很可能是正确的。尝试通过订阅读取已解析的数据:

this.route.data.subscribe(d => this.user = d['user']['data']);

关于Angular 2 Resolve 只工作一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42092958/

相关文章:

javascript - Angular http 客户端可观察管道图

angular - 如何在 ngrx 效果中使用 LatestFrom 进行单元测试

javascript - 为每个订阅在扫描运算符上创建一个新的种子对象

javascript - 如何从这两个可观察对象中只创建一个订阅?

javascript - 如何干净地重新连接到 ReplaySubject,同时避免过去的内存副作用?

angular - 通过映射将类型(接口(interface))转换为可观察的

Angular 4/5 - 路线 paramMap 与 params

Angular - 在继承中使用变量作为类型

javascript - 单步进入数据流并输出经过过滤的数据数组 Rxjs

javascript - 在共享服务和组件之间使用 Observable 发出数据