看@inject可以知道,inject需要传入一个InjectionToken类,该类需要传入providedIn和factory函数,代码如下:
export declare class InjectionToken<T> {
protected _desc: string;
readonly ɵprov: never | undefined;
constructor(_desc: string, options?: {
providedIn?: Type<any> | 'root' | 'platform' | 'any' | null;
factory: () => T;
});
toString(): string;
}
所以就有了这段代码:
const Test = new InjectionToken<any>('test',{
providedIn:'root',
factory:()=>'12465'
})
随后我就将Test传入了@Inject,并打印传出的值showTest
export class DragDirective {
constructor(
@Inject(PLATFORM_ID) private platformId,
@Inject(Test) private showTest,
) {
console.log(this.showTest);
}
}
可以看到,打印的值就是factory函数的返回值,由此我们可以得出结论@inject所处理的逻辑都是放在factory函数中。
那么这种方式适用于那些情况呢?比如判断是否为浏览器PLATFORM_ID,类似于该类独立于你的代码,可以被注入任何地方都可以用这种@inject的方式。那么执行时机是什么时候呢?我们来打印一下。
const SET_TOKEN = new InjectionToken<any>('存储固定token',{
providedIn:'root',
factory:()=>{
console.log('执行inject');
window.localStorage.setItem('token','123465')
}
})
export class DragDirective {
constructor(
@Inject(SET_TOKEN) private showTest,
) {
// console.log(this.showTest);
}
}
可以发现在被注入的时候就已经执行了,接下来带大家模仿下angular的PLATFORM_ID执行过程,直接上代码:
const PLATFORM_MY = new InjectionToken<any>('获取环境', {
providedIn: 'root',
factory: () => {
console.log('执行inject');
const ua = navigator.userAgent.toLowerCase()