use*_*220 52 interface inject angular
我想知道是否有一种在Angular2中注入接口的正确方法?(参见下文)
我认为这与接口上缺少的@Injectable()装饰器有关,但似乎不允许这样做.
问候.
当CoursesServiceInterface作为接口实现时,TypeScript编译器会抱怨"CoursesServiceInterface找不到名称":
import {CoursesServiceInterface} from './CoursesService.interface';
import {CoursesService} from './CoursesService.service';
import {CoursesServiceMock} from './CoursesServiceMock.service';
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
GlobalService,
provide(CoursesServiceInterface, { useClass: CoursesServiceMock })
]);
Run Code Online (Sandbox Code Playgroud)
但是使用CoursesServiceInterface作为接口:
import {Injectable} from 'angular2/core';
import {Course} from './Course.class';
//@Injectable()
export interface CoursesServiceInterface {
getAllCourses(): Promise<Course[]>;//{ return null; };
getCourse(id: number): Promise<Course>;// { return null; };
remove(id: number): Promise<{}>;// { return null; };
}
Run Code Online (Sandbox Code Playgroud)
当service是一个类时,TypeScript编译器不再抱怨:
import {Injectable} from 'angular2/core';
import {Course} from './Course.class';
@Injectable()
export class CoursesServiceInterface {
getAllCourses() : Promise<Course[]> { return null; };
getCourse(id: number) :Promise<Course> { return null; };
remove (id: number) : Promise<{}> { return null; };
}
Run Code Online (Sandbox Code Playgroud)
Gün*_*uer 81
不,DI不支持接口.由于TypeScript接口在运行时不再可用,因此只能静态使用,因此不能用作DI令牌.
或者,您可以使用字符串作为键或 InjectionToken
provide('CoursesServiceInterface', {useClass: CoursesServiceMock}) // old
Run Code Online (Sandbox Code Playgroud)
providers: [{provide: 'CoursesServiceInterface', useClass: CoursesServiceMock}]
Run Code Online (Sandbox Code Playgroud)
并注入它
constructor(@Inject('CoursesServiceInterface') private coursesService:CoursesServiceInterface) {}
Run Code Online (Sandbox Code Playgroud)
另请参见https://angular.io/api/core/InjectionToken
Tob*_*obi 52
您无法使用接口的原因是因为接口是TypeScript设计时工件.JavaScript没有接口.TypeScript接口从生成的JavaScript中消失.Angular没有留下接口类型信息以便在运行时查找.
解决方案1:
最简单的解决方案就是定义一个实现接口的抽象类.通常,无论如何你都需要一个抽象类.
接口:
import {Role} from "../../model/role";
export interface ProcessEngine {
login(username: string, password: string):string;
getRoles(): Role[];
}
Run Code Online (Sandbox Code Playgroud)
抽象类:
import {ProcessEngine} from "./process-engine.interface";
export abstract class ProcessEngineService implements ProcessEngine {
abstract login(username: string, password: string): string;
abstract getRoles(): Role[];
}
Run Code Online (Sandbox Code Playgroud)
具体类:
import { Injectable } from '@angular/core';
import {ProcessEngineService} from "./process-engine.service";
@Injectable()
export class WebRatioEngineService extends ProcessEngineService {
login(username: string, password: string) : string {...}
getRoles(): Role[] {...}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以像往常一样定义您的提供商:
@NgModule({
...
providers: [
...,
{provide: ProcessEngineService, useClass: WebRatioEngineService}
]
})
Run Code Online (Sandbox Code Playgroud)
解决方案2:
Angular的官方文档建议使用InjectionToken,类似于OpaqueToken.这是一个例子:
你的界面和课程:
export interface AppConfig {
apiEndpoint: string;
title: string;
}
export const HERO_DI_CONFIG: AppConfig = {
apiEndpoint: 'api.heroes.com',
title: 'Dependency Injection'
};
Run Code Online (Sandbox Code Playgroud)
定义您的令牌:
import { InjectionToken } from '@angular/core';
export let APP_CONFIG = new InjectionToken<AppConfig>('app.config');
Run Code Online (Sandbox Code Playgroud)
使用InjectionToken对象注册依赖项提供程序,例如在app.module.ts中:
providers: [{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }]
Run Code Online (Sandbox Code Playgroud)
在@Inject装饰器的帮助下,您可以将配置对象注入任何需要它的构造函数中:
constructor(@Inject(APP_CONFIG) config: AppConfig) {
this.title = config.title;
}
Run Code Online (Sandbox Code Playgroud)
角度 9 的替代解决方案
@Injectable()
export class TodoListPublicService implements TodoListService {
getTodos(): Todo[] {
const todos: Todo[] = [
{
title: 'get groceries',
description: 'eggs, milk, etc.',
done: false
}
];
return todos;
}
}
Run Code Online (Sandbox Code Playgroud)
创建一个抽象类
export interface Todo {
title: string;
description: string;
done: boolean;
}
@Injectable()
export abstract class TodoListService {
abstract getTodos(): Todo[];
}
Run Code Online (Sandbox Code Playgroud)
在组件中使用
providers: [
{ provide: TodoListService, useClass: TodoListPublicService }
]
export class TodoListComponent implements OnInit {
todos: Todo[];
constructor(private todoListService: TodoListService) { }
ngOnInit() {
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
31578 次 |
| 最近记录: |