Chcę wstrzyknąć usługę do klasy, która nie jest składnikiem .
Na przykład:
Myservice
import {Injectable} from '@angular/core';
@Injectable()
export class myService {
dosomething() {
// implementation
}
}
Moja klasa
import { myService } from './myService'
export class MyClass {
constructor(private myservice:myService) {
}
test() {
this.myservice.dosomething();
}
}
To rozwiązanie nie działa (myślę, że MyClass
nie zostało jeszcze utworzone).
Czy istnieje inny sposób używania usługi w klasie (nie komponentu)? A może uważasz, że mój projekt kodu jest nieodpowiedni (aby używać usługi w klasie, która nie jest komponentem)?
Dziękuję Ci.
źródło
private
nie jest konieczne, ponieważinjector
nie jest używane poza konstruktorem, dlatego nie ma potrzeby utrzymywania odwołania w polu.Nie jest to bezpośrednia odpowiedź na pytanie, ale jeśli czytasz to SO z powodu, dla którego jestem, może to pomóc ...
Powiedzmy, że używasz ng2-translate i naprawdę chcesz, aby Twoja
User.ts
klasa to miała. Od razu myślisz, że użyjesz DI, aby go umieścić, w końcu robisz Angular. Ale to trochę przesadne myślenie, możesz po prostu przekazać to w swoim konstruktorze lub uczynić z niego zmienną publiczną, którą ustawiłeś z komponentu (gdzie prawdopodobnie to zrobiłeś DI).na przykład:
import { TranslateService } from "ng2-translate"; export class User { public translateService: TranslateService; // will set from components. // a bunch of awesome User methods }
następnie z jakiegoś komponentu związanego z użytkownikiem, który wstrzyknął TranslateService
addEmptyUser() { let emptyUser = new User("", ""); emptyUser.translateService = this.translateService; this.users.push(emptyUser); }
Mam nadzieję, że pomoże to tym, którzy są tacy jak ja, którzy mieli napisać dużo trudniejszy w utrzymaniu kod, ponieważ czasami jesteśmy zbyt sprytni =]
(UWAGA: powodem, dla którego możesz chcieć ustawić zmienną zamiast uczynić ją częścią swojej metody konstruktora, jest to, że możesz mieć przypadki, w których nie musisz używać usługi, więc zawsze konieczność jej przekazania oznaczałaby wprowadzenie dodatkowego importu / kod, który nigdy nie jest używany)
źródło
translateService
get / set, w którymget
rzuca znaczący błąd zamiast wyjątku NullReference, jeśli zapomniałeś go ustawićTo trochę ( bardzo ) hackerskie, ale pomyślałem, że podzielę się również moim rozwiązaniem. Zwróć uwagę, że zadziała to tylko z usługami Singleton (wstrzykniętymi w katalogu głównym aplikacji, a nie komponentem!), Ponieważ działają one tak długo, jak Twoja aplikacja i istnieje tylko jedna ich instancja.
Po pierwsze, w twojej służbie:
@Injectable() export class MyService { static instance: MyService; constructor() { MyService.instance = this; } doSomething() { console.log("something!"); } }
Następnie w dowolnej klasie:
export class MyClass { constructor() { MyService.instance.doSomething(); } }
To rozwiązanie jest dobre, jeśli chcesz zmniejszyć bałagan w kodzie i i tak nie korzystasz z usług innych niż pojedyncze.
źródło
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 }
źródło
injector.get()
wywołania do modułu zadziała (przy założeniu, że usługa bezstanowa jest taka, że kilka klas może „współużytkować” to samo wystąpienie)?Jeśli metody usługi są czystymi funkcjami, prostym sposobem rozwiązania tego problemu jest posiadanie statycznych elementów członkowskich w usłudze.
Twoja usługa
import {Injectable} from '@angular/core'; @Injectable() export class myService{ public static dosomething(){ //implementation => doesn't use `this` } }
Twoja klasa
export class MyClass{ test(){ MyService.dosomething(); //no need to inject in constructor } }
źródło