typescript - Angular 15 - Considere usar o decorador @Inject para especificar um token de injeção
Depois de usar o provedor de fábrica do Angular e enviar dois argumentos em factory.service.ts, eu queria exibir 'factory' e um valor booleano.
Parece funcionar bem em outras versões do Angular, mas ocorre um problema na versão 15 do Angular.
Eu não sei qual parte é o problema....
home.component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { FactoryService } from '../factory.service';
import { LogService } from '../log.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
providers: [LogService,
{provide: 'another', useClass: LogService},
{provide: 'same',useExisting: LogService},
{provide: 'githubUrl',useValue: 'https://github.com/abcd'},
{provide: 'factory',useFactory: (logService) => {
return new FactoryService(logService, true);},
deps: [FactoryService]
}]
})
export class HomeComponent implements OnInit{
constructor(private log:LogService,
@Inject('another') private another,
@Inject('same') private same,
@Inject('githubUrl') private url,
@Inject('factory') private factory
) {
console.log("this.log === this.another", this.log === this.another)
console.log("this.log === this.same", this.log === this.same)
console.log(this.url)
}
ngOnInit(): void {
this.log.info('logservice');
this.factory.log();
}
}
fábrica.serviço.ts
import { Inject, Injectable } from "@angular/core";
import { LogService } from "./log.service";
@Injectable()
export class FactoryService {
constructor(private logService: LogService, private isFactory: boolean) {}
public log() {
this.logService.info(`factory ${this.isFactory}`);
}
}
Erro
Error: src/app/factory.service.ts:6:57 - error NG2003: No suitable injection token for parameter 'isFactory' of class 'FactoryService'.
Consider using the @Inject decorator to specify an injection token.
6 constructor(private logService: LogService, private isFactory: boolean) {}
~~~~~~~~~
src/app/factory.service.ts:6:68
6 constructor(private logService: LogService, private isFactory: boolean) {}
~~~~~~~
This type is not supported as injection token.
Eu olhei a documentação oficial, mas não sei qual é o problema.
Resposta #1
A maneira mais simples de resolver é usar tokens de injeção. Se você usar factory, então eles podem ser eliminados pelo tree-shaking.
const IS_FACTORY = new InjectionToken<boolean>('Is factory', {
providedIn: 'root', // optional
factory: () => true
});
Para fornecer,
providers: [{ provide: IS_FACTORY, useValue: false}],
E se você quiser usar no seu componente com segurança de tipo
const isFactory = inject(IS_FACTORY); // or the @Inject method
O segundo argumento de inject permite os modificadores de resolução usuais como optional, self, host, etc.
Resposta #2
Conforme sugerido pela mensagem de erro, você deve usar o decorador @Inject para seu parâmetro personalizado, caso contrário o Angular irá tratá-lo como uma dependência e tentar resolvê-lo.
Como você não tem um provedor isFactory desse tipo, o Angular lançou um erro.
Adicione o decorador @Inject com o nome isFactory
fábrica.serviço.ts
......
constructor(private logService: LogService, @Inject('isFactory') private isFactory: boolean) {}
......
Forneça o valor isFactory e remova o segundo parâmetro em new FactoryService
home.component.ts
......
providers: [LogService,
{provide: 'another', useClass: LogService},
{provide: 'same',useExisting: LogService},
{provide: 'githubUrl',useValue: 'https://github.com/abcd'},
{
provide: 'isFactory',
useValue: true,
},
{provide: 'factory',useFactory: (logService) => {
return new FactoryService(logService);},
deps: [FactoryService]
},
]
})
O código não está testado.
Consulte https://www.positronx.io/how-to-pass-parameters-to-angular-service-using-inject/ para mais informações.
