提供的管道无权访问路由解析数据
Provided Pipe doesn't have access to route resolved data
我有一个管道需要访问路由数据才能很好地构建:
export class LevelPercentagePipe implements PipeTransform {
levelDictionnary: LevelDictionnary;
constructor(private route: ActivatedRoute) {
this.levelDictionnary = new LevelDictionnary(this.route.snapshot.data['prerequisiteLists']);
}
}
此数据在路由模块中解析:
{
path: 'xxx',
loadChildren: './xxx/xxx.module#XxxModule',
resolve: {
prerequisiteLists: PrerequisiteResolver
}
}
如果在 html 模板中使用管道,它在我的应用程序的其他地方也有效。
但在这种特殊情况下,我需要在我的 component.ts
文件中使用这个管道。所以我在具体的功能模块中提供了它:
@NgModule({
declarations: [...],
imports: [...],
providers: [LevelFilterPipe],
})
但现在当它被注入我的组件构造函数时,它似乎不知道 ActivatedRoute
中的数据。
constructor(
private profileService: ProfileService,
private nameFilterPipe: NameFilterPipe,
private levelFilterPipe: LevelFilterPipe
) {}
这行不通。
所以我需要手动构建管道。
constructor(
private profileService: ProfileService,
private route: ActivatedRoute,
private scorePipe: ScorePipe,
private nameFilterPipe: NameFilterPipe
) {
// We have to inject route data and scorePipe manually because it's not injected automatically.
this.levelFilterPipe = new LevelFilterPipe(this.route, this.scorePipe);
}
还有其他方法可以自动从 ActivatedRoute
注入数据吗?
管道不是供应商。将管道放在组件的提供者数组中不会有太大作用。
如果你想让它工作,你可以简单地在你的组件中创建你的管道实例并传递当前路由。
constructor(private route: ActivatedRoute) {
const pipeInstance = new MyPipe(ths.route);
}
你也可以尝试在你的管道中注入,像这样:
constructor(@Inject(forwardRef(() => ActivatedRoute)) private route: ActivatedRoute) {}
但我不确定这是否可行。
由于 Pipe 只是另一个 TypeScript class,如果用 @Injectable()
装饰器装饰,它可以作为依赖项注入。
因此,如果您在管道上方添加 @Injectable()
,那么您的第一种方法将会奏效。
像这样:
import { Pipe, PipeTransform, Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Injectable()
@Pipe({
name: 'level-filter'
})
export class LevelFilterPipe implements PipeTransform {
constructor(private activatedRoute: ActivatedRoute) {}
transform(value: any, args?: any): any {
...
}
}
Here's a Sample Working StackBlitz Example for your ref.
PS: 不太确定这是否是一件好事。
您需要将 pipe
添加到您组件的供应商列表中。现在,您的管道注入将使用更新后的 ActivatedRoute
数据创建管道的新实例。
@Component({
selector: '...',
template: `...`:
providers: [ YourPipeName ]
})
这是您问题的有效 StackBlitz project 示例。查看文件 hello.component.ts
,此组件使用您提到的参数进行路由,删除此组件中提供的管道以重现您的问题。
我有一个管道需要访问路由数据才能很好地构建:
export class LevelPercentagePipe implements PipeTransform {
levelDictionnary: LevelDictionnary;
constructor(private route: ActivatedRoute) {
this.levelDictionnary = new LevelDictionnary(this.route.snapshot.data['prerequisiteLists']);
}
}
此数据在路由模块中解析:
{
path: 'xxx',
loadChildren: './xxx/xxx.module#XxxModule',
resolve: {
prerequisiteLists: PrerequisiteResolver
}
}
如果在 html 模板中使用管道,它在我的应用程序的其他地方也有效。
但在这种特殊情况下,我需要在我的 component.ts
文件中使用这个管道。所以我在具体的功能模块中提供了它:
@NgModule({
declarations: [...],
imports: [...],
providers: [LevelFilterPipe],
})
但现在当它被注入我的组件构造函数时,它似乎不知道 ActivatedRoute
中的数据。
constructor(
private profileService: ProfileService,
private nameFilterPipe: NameFilterPipe,
private levelFilterPipe: LevelFilterPipe
) {}
这行不通。
所以我需要手动构建管道。
constructor(
private profileService: ProfileService,
private route: ActivatedRoute,
private scorePipe: ScorePipe,
private nameFilterPipe: NameFilterPipe
) {
// We have to inject route data and scorePipe manually because it's not injected automatically.
this.levelFilterPipe = new LevelFilterPipe(this.route, this.scorePipe);
}
还有其他方法可以自动从 ActivatedRoute
注入数据吗?
管道不是供应商。将管道放在组件的提供者数组中不会有太大作用。
如果你想让它工作,你可以简单地在你的组件中创建你的管道实例并传递当前路由。
constructor(private route: ActivatedRoute) {
const pipeInstance = new MyPipe(ths.route);
}
你也可以尝试在你的管道中注入,像这样:
constructor(@Inject(forwardRef(() => ActivatedRoute)) private route: ActivatedRoute) {}
但我不确定这是否可行。
由于 Pipe 只是另一个 TypeScript class,如果用 @Injectable()
装饰器装饰,它可以作为依赖项注入。
因此,如果您在管道上方添加 @Injectable()
,那么您的第一种方法将会奏效。
像这样:
import { Pipe, PipeTransform, Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Injectable()
@Pipe({
name: 'level-filter'
})
export class LevelFilterPipe implements PipeTransform {
constructor(private activatedRoute: ActivatedRoute) {}
transform(value: any, args?: any): any {
...
}
}
Here's a Sample Working StackBlitz Example for your ref.
PS: 不太确定这是否是一件好事。
您需要将 pipe
添加到您组件的供应商列表中。现在,您的管道注入将使用更新后的 ActivatedRoute
数据创建管道的新实例。
@Component({
selector: '...',
template: `...`:
providers: [ YourPipeName ]
})
这是您问题的有效 StackBlitz project 示例。查看文件 hello.component.ts
,此组件使用您提到的参数进行路由,删除此组件中提供的管道以重现您的问题。