Angular — InjectionToken с параметром

у меня естьInjectionTokenнравиться:

      export const SOURCE_DATA_INJECTION_TOKEN =
    new InjectionToken<CustomObject[]>('All Source Data', {
      providedIn: 'root',
      factory: () => {
        // Returns all source
        return someArrayData // This data is read from a local .json file;
      }
    });

И мой компонент использует его напрямую, как следует,

      @Component({})
export class SourceManager {
  sourceDataList: CustomObject[] = inject(SOURCE_DATA_INJECTION_TOKEN);
}

Теперь мне нужно обновить свой INJECTION_TOKEN, чтобы он возвращал данные на основе источника, выбранного пользователем в компоненте. Обновления в компоненте будут выглядеть так:

      @Component({})
export class SourceManager {
  selectedSource: SourceEnum = SourceEnum.SomeSource1

  sourceDataList: CustomObject[] = inject(SOURCE_DATA_INJECTION_TOKEN);
}

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

Я вижу, что фабричный метод также может иметь параметр, могу ли я как-то передатьselectedSourceк этому?

1 ответ

К сожалению, без изменения SOURCE_DATA_INJECTION_TOKEN на наблюдаемый у вас не так уж много вариантов. Сейчас я могу думать только об этом

https://stackblitz.com/edit/angular-easguk?file=src%2Fmain.ts

      
type Datum = {
  id: string;
};
export const SOURCE_ADD_TOKEN = new InjectionToken<Subject<Datum>>(
  'Add Source',
  {
    providedIn: 'root',
    factory: () => new Subject<Datum>(),
  }
);

export const SOURCE_DATA_INJECTION_TOKEN = new InjectionToken<Datum[]>(
  'All Source Data',
  {
    providedIn: 'root',
    factory: () => {
      let items = [{ id: '0' }];
      inject(SOURCE_ADD_TOKEN).subscribe((newItem) => {
        items.push(newItem);
      });
      return items;
    },
  }
);

@Component({
  selector: 'my-app',
  standalone: true,
  template: `
     We have {{data.length}} item(s)
     <button (click)="onChangeClick()">Add</button>
  `,
})
export class App {
  public data = inject(SOURCE_DATA_INJECTION_TOKEN);

  private add$ = inject(SOURCE_ADD_TOKEN);

  onChangeClick() {
    this.add$.next({ id: nanoid() });
  }
}
Другие вопросы по тегам