【问题标题】:Resolve guard in Nativescript在 Nativescript 中解析守卫
【发布时间】:2019-09-20 17:11:28
【问题描述】:

我正在尝试在 Nativescript 中为名为“rewards”的路由实现解析保护,但无法使其正常工作。

问题 - 如果我在路由配置中使用解析防护,则 RewardListComponent 永远不会被激活 - 它卡在“ResolveStart”(请参见下面的屏幕截图),但一旦我移除解析防护,组件就会被激活。

请指导我在哪里出错。

路由器跟踪日志

rewards-routing.module.ts

import { NgModule } from "@angular/core";
import { Routes } from "@angular/router";
import { NativeScriptRouterModule } from "nativescript-angular/router";

import { RewardsListResolverService } from "./services/rewards-list-resolver.service";

import { RewardsListComponent } from "./components/rewards-list/rewards-list.component";

const routes: Routes = [
    {
        path: "rewards",
        component: RewardsListComponent,
        resolve: {
            rewards: RewardsListResolverService
        }
    }
];

@NgModule({
    imports: [NativeScriptRouterModule.forChild(routes)],
    exports: [NativeScriptRouterModule]
})
export class RewardsRoutingModule {}

rewards.module.ts

import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';

import { RewardsRoutingModule } from './rewards-routing.module';
import { NativeScriptCommonModule } from 'nativescript-angular/common';
import { NativeScriptFormsModule } from 'nativescript-angular/forms';

import { RewardsService } from './services/rewards.service';
import { RewardsListResolverService } from './services/rewards-list-resolver.service';

import { RewardsListComponent } from './components/rewards-list/rewards-list.component';

@NgModule({
  declarations: [RewardsListComponent],
  imports: [
    RewardsRoutingModule,
    NativeScriptCommonModule,
    NativeScriptFormsModule
  ],
  schemas: [NO_ERRORS_SCHEMA],
  providers: [
      RewardsService,
      RewardsListResolverService
  ]
})
export class RewardsModule { }

rewards-list-resolver.service

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { SimpleReward } from '../models/simple-reward';
import { Observable } from 'rxjs';
import { RewardsService } from './rewards.service';

@Injectable()
export class RewardsListResolverService implements Resolve<SimpleReward[]> {

  constructor(private rewardsService: RewardsService) { }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<SimpleReward[]> {
      return this.rewardsService.getAllRewards();
  }

}

rewards-list.component.ts

import { Component, OnInit, OnDestroy } from "@angular/core";
import { Subscription } from "rxjs";

import { SimpleReward } from '../../models/simple-reward';

@Component({
    templateUrl: "./rewards-list.component.html",
    moduleId: module.id
})
export class RewardsListComponent implements OnInit, OnDestroy {

    rewards: SimpleReward[];

    private subscriptions: Subscription[] = [];

    constructor() {}

    ngOnInit() {
        console.log('Activated');
        // this.subscribeToResolvedData();
    }

    ngOnDestroy(): void {
        this.subscriptions.forEach(x => x.unsubscribe());
    }
}

rewards.service.ts

import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";

import { Observable } from 'rxjs';
import { SimpleReward } from "../models/simple-reward";

@Injectable()
export class RewardsService {

    private baseUrl = "http://10.0.2.2:52553/api/rewards";

    constructor(private http: HttpClient) {}

    getAllRewards(): Observable<SimpleReward[]> {
        const url = `${this.baseUrl}/all`;
        return this.http.get<SimpleReward[]>(url);
    }
}

【问题讨论】:

  • 你能展示一下this.rewardsService.getAllRewards()的实现吗?附带说明,如果你想在你的应用程序中有奇怪的错误,请使用NO_ERRORS_SCHEMA :)
  • 感谢您的回复!我已经添加了奖励服务的实现

标签: angular nativescript


【解决方案1】:

您的服务请求似乎没有完成,但我不明白为什么。你可以试试这个,也许这会揭示一个错误:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<SimpleReward[]> {
  return this.rewardsService.getAllRewards().pipe(
    take(1),
    catchError((e) => {
      console.error(e);
      return of([]);
    })
  );
}

如果这不起作用,请尝试将您的解析器更改为:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<SimpleReward[]> {
  return of([]);
}

如果这确实有效,您可以确定您的服务调用中有问题。你确定它返回的是一个正常的 200 状态的数组吗?

【讨论】:

  • 很奇怪。我尝试了您的第一个建议,它没有任何控制台错误,我看到组件已被激活并显示已解析的数据(来自 API)。第二个建议也奏效了。但是,如果我再次将解析器更改为“this.rewardsService.getAllRewards();”然后同样的问题再次出现 - 我可以在网络选项卡中看到 API 调用返回 200。
  • 您可以保留第一个解决方案,它会响应收到的第一个响应并立即完成。但奇怪的是http调用没有完成。你在那里做的一些流式http请求吗?用 HttpInterceptor 什么的?
  • 感谢您的指出 - 我已实施 HttpInterceptor 以添加不记名令牌,导致 GET 请求永远无法完成。我明白为什么 take(1) 有效。我已经修复了拦截器中的错误,现在一切都按预期工作。再次感谢您的帮助!
【解决方案2】:

我认为您应该在 rewards-routing.module.ts 中添加 providers 数组,并在此处提供您的解析器。

@NgModule({
    imports: [NativeScriptRouterModule.forChild(routes)],
    exports: [NativeScriptRouterModule],
    providers: [RewardsListResolverService]
})

【讨论】:

  • 我试过但同样的问题。据我所知,我认为在路由模块或功能模块中定义服务不会有任何区别。
  • 当您提供rewards.service.ts 我知道您需要订阅getAllRewards()。否则,什么都不会发生。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-27
  • 2013-03-31
  • 1970-01-01
  • 1970-01-01
  • 2019-04-25
相关资源
最近更新 更多