Je souhaite injecter un service dans une classe qui n'est pas un composant .
Par exemple:
Mon service
import {Injectable} from '@angular/core';
@Injectable()
export class myService {
dosomething() {
// implementation
}
}
Ma classe
import { myService } from './myService'
export class MyClass {
constructor(private myservice:myService) {
}
test() {
this.myservice.dosomething();
}
}
Cette solution ne fonctionne pas (je pense parce qu'elle MyClass
n'a pas encore été instanciée).
Existe-t-il une autre façon d'utiliser un service dans une classe (pas un composant)? Ou considérez-vous ma conception de code comme inappropriée (pour utiliser un service dans une classe qui n'est pas un composant)?
Merci.
la source
private
n'est pas nécessaire, car ilinjector
n'est pas utilisé en dehors du constructeur, donc pas besoin de conserver une référence dans un champ.Pas une réponse directe à la question, mais si vous lisez ce SO pour la raison que je suis, cela peut aider ...
Disons que vous utilisez ng2-translate et que vous voulez vraiment que votre
User.ts
classe l'ait. Vous pensez immédiatement utiliser DI pour le mettre, vous faites Angular après tout. Mais c'est un peu trop réfléchir, vous pouvez simplement le passer dans votre constructeur ou en faire une variable publique que vous avez définie à partir du composant (où vous l'avez probablement fait).par exemple:
import { TranslateService } from "ng2-translate"; export class User { public translateService: TranslateService; // will set from components. // a bunch of awesome User methods }
puis à partir d'un composant lié à l'utilisateur qui a injecté TranslateService
addEmptyUser() { let emptyUser = new User("", ""); emptyUser.translateService = this.translateService; this.users.push(emptyUser); }
J'espère que cela aidera ceux qui, comme moi, étaient sur le point d'écrire du code beaucoup plus difficile à maintenir parce que nous sommes parfois trop intelligents =]
(REMARQUE: la raison pour laquelle vous voudrez peut-être définir une variable au lieu de l'inclure dans votre méthode de constructeur est que vous pourriez avoir des cas où vous n'avez pas besoin d'utiliser le service, donc toujours être obligé de le transmettre signifierait l'introduction d'importations supplémentaires / code qui ne sont jamais vraiment utilisés)
la source
translateService
un get / set où leget
lance une erreur significative au lieu d'une exception NullReference si vous avez oublié de le définirC'est un peu ( très ) hacky, mais j'ai pensé partager ma solution aussi. Notez que cela ne fonctionnera qu'avec les services Singleton (injectés à la racine de l'application, pas dans le composant!), Car ils vivent aussi longtemps que votre application, et il n'y en a qu'une seule instance.
Tout d'abord, à votre service:
@Injectable() export class MyService { static instance: MyService; constructor() { MyService.instance = this; } doSomething() { console.log("something!"); } }
Puis dans n'importe quelle classe:
export class MyClass { constructor() { MyService.instance.doSomething(); } }
Cette solution est bonne si vous souhaitez réduire l'encombrement du code et n'utilisez pas de services non singleton de toute façon.
la source
locator.service.ts
import {Injector} from "@angular/core"; export class ServiceLocator { static injector: Injector; }
app.module.ts
@NgModule({ ... }) export class AppModule { constructor(private injector: Injector) { ServiceLocator.injector = injector; } }
poney.model.ts
export class Poney { id: number; name: string; color: 'black' | 'white' | 'brown'; service: PoneyService = ServiceLocator.injector.get(PoneyService); // <--- HERE !!! // PoneyService is @injectable and registered in app.module.ts }
la source
injector.get()
appel vers le module fonctionnera-t-il (en supposant un service sans état afin que plusieurs classes puissent «partager» la même instance)?Si vos méthodes de service sont des fonctions pures, un moyen propre de résoudre ce problème consiste à avoir des membres statiques dans votre service.
ton service
import {Injectable} from '@angular/core'; @Injectable() export class myService{ public static dosomething(){ //implementation => doesn't use `this` } }
ta classe
export class MyClass{ test(){ MyService.dosomething(); //no need to inject in constructor } }
la source