Предоставленный канал не имеет доступа к данным, разрешенным по маршруту - PullRequest
0 голосов
/ 28 декабря 2018

У меня есть канал, который должен иметь доступ к данным маршрута, чтобы быть правильно построенным:

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 автоматически?

Ответы [ 3 ]

0 голосов
/ 28 декабря 2018

Поскольку Pipe - это просто еще один класс TypeScript, его можно внедрить в качестве зависимости, если он украшен декоратором @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 {
    ...
  }

}

Вот пример Пример рабочего StackBlitz для вашей ссылки.

PS: Не совсем уверен, хорошо ли это делать.

0 голосов
/ 30 декабря 2018

Вам нужно добавить свой pipe в список поставщиков вашего компонента.Теперь ваша инъекция в трубу создаст новый экземпляр вашей трубы с обновленными данными ActivatedRoute.

@Component({
  selector: '...',
  template: `...`:
  providers: [ YourPipeName ]
})

Вот рабочий проект StackBlitz пример вашего вопроса.Посмотрите на файл hello.component.ts, этот компонент направляется с параметром, как вы упомянули, удалите предоставленный канал в этом компоненте, чтобы воспроизвести вашу проблему.

0 голосов
/ 28 декабря 2018

Трубы не являются поставщиками.Помещение канала в массив провайдеров компонента не принесет особых результатов.

Если вы хотите, чтобы он работал, вы можете просто создать экземпляр своего канала в вашем компоненте и пропустить текущий маршрут.

constructor(private route: ActivatedRoute) {
  const pipeInstance = new MyPipe(ths.route);
}

Вы также можете попробовать сделать инъекцию в свою трубу, примерно так:

constructor(@Inject(forwardRef(() => ActivatedRoute)) private route: ActivatedRoute) {}

Но я не уверен, что это сработает.

...