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() });
}
}