컴포넌트 가 아닌 클래스에 서비스를 삽입하고 싶습니다 .
예를 들면 :
Myservice
import {Injectable} from '@angular/core';
@Injectable()
export class myService {
dosomething() {
// implementation
}
}
내 수업
import { myService } from './myService'
export class MyClass {
constructor(private myservice:myService) {
}
test() {
this.myservice.dosomething();
}
}
이 솔루션은 작동하지 않습니다 ( MyClass
아직 인스턴스화되지 않았기 때문에 생각합니다 ).
구성 요소가 아닌 클래스에서 서비스를 사용하는 다른 방법이 있습니까? 아니면 내 코드 디자인이 부적절하다고 생각하십니까 (컴포넌트가 아닌 클래스에서 서비스를 사용하는 것)?
감사합니다.
답변
주입은 Angulars DI (종속성 주입)에 의해 인스턴스화 된 클래스에서만 작동합니다.
- 당신은
- 추가
@Injectable()
로MyClass
및 - 제공
MyClass
과 같은providers: [MyClass]
구성 요소 또는 NgModule있다.
- 추가
그런 다음 MyClass
어딘가에 주입하면 DI에 의해 인스턴스화 될 때 MyService
인스턴스가 전달됩니다 MyClass
(처음 주입되기 전).
- 다른 방법은 다음과 같은 사용자 지정 인젝터를 구성하는 것입니다.
constructor(private injector:Injector) {
let resolvedProviders = ReflectiveInjector.resolve([MyClass]);
let childInjector = ReflectiveInjector.fromResolvedProviders(resolvedProviders, this.injector);
let myClass : MyClass = childInjector.get(MyClass);
}
이 방법 myClass
은 MyClass
Angulars DI에 의해 인스턴스화 된 인스턴스가되고 인스턴스화 myService
될 때 주입됩니다 MyClass
. 지시문 내에서 수동으로 Injector에서 종속성 가져 오기를
참조하십시오.
- 또 다른 방법은 인스턴스를 직접 만드는 것입니다.
constructor(ms:myService)
let myClass = new MyClass(ms);
답변
질문에 대한 직접적인 대답은 아니지만이 글을 읽는다면 도움이 될 수 있습니다.
당신이 사용하고 있다고 가정 해 봅시다. ng2-translate를 사용 하고 있고 당신의 User.ts
수업에 정말로 그것을 원한다고 . DI를 사용하여 삽입하는 것이 즉각적인 생각이며 결국 Angular를 수행하고 있습니다. 그러나 그것은 지나치게 생각하는 것입니다. 생성자에 전달하거나 구성 요소에서 설정 한 공용 변수로 만들 수 있습니다 (아마도 DI를 수행 한 위치).
예 :
import { TranslateService } from "ng2-translate";
export class User {
public translateService: TranslateService; // will set from components.
// a bunch of awesome User methods
}
그런 다음 TranslateService를 주입 한 일부 사용자 관련 구성 요소에서
addEmptyUser() {
let emptyUser = new User("", "");
emptyUser.translateService = this.translateService;
this.users.push(emptyUser);
}
바라건대 이것은 우리가 때때로 너무 영리하기 때문에 코드를 유지하기가 훨씬 더 어려운 저 같은 사람들에게 도움이되기를 바랍니다 =]
(참고 : 생성자 메서드의 일부로 만드는 대신 변수를 설정하려는 이유는 서비스를 사용할 필요가없는 경우가있을 수 있으므로 항상 전달해야한다는 것은 추가 가져 오기를 도입하는 것을 의미합니다. / 실제로 사용되지 않는 코드)
답변
이것은 일종의 ( 매우 ) 해키이지만 내 솔루션도 공유 할 것이라고 생각했습니다. Singleton 서비스 (컴포넌트가 아닌 앱 루트에 주입 됨) 에서만 작동 합니다. 애플리케이션만큼 오래 살며 인스턴스가 하나뿐이기 때문입니다.
첫째, 서비스에서 :
@Injectable()
export class MyService {
static instance: MyService;
constructor() {
MyService.instance = this;
}
doSomething() {
console.log("something!");
}
}
그런 다음 모든 수업에서 :
export class MyClass {
constructor() {
MyService.instance.doSomething();
}
}
이 솔루션은 코드 혼란을 줄이고 어쨌든 비 단일 서비스를 사용하지 않는 경우에 좋습니다.
답변
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
}
답변
서비스 메서드가 순수 함수 인 경우이를 해결하는 깨끗한 방법은 서비스에 정적 멤버를 포함하는 것입니다.
당신의 서비스
import {Injectable} from '@angular/core';
@Injectable()
export class myService{
public static dosomething(){
//implementation => doesn't use `this`
}
}
당신의 수업
export class MyClass{
test(){
MyService.dosomething(); //no need to inject in constructor
}
}