今日完成:
angular中的依赖注入
一个登陆组件的简单demo:
<div>
<input #usernameRef type="text">
<input #passwordRef type="password">
<button (click)="Login(usernameRef.value,passwordRef.value)">Login</button>
</div>
然后对输入的用户名进行验证,业务逻辑直接写在Login方法中也可以。但是这样做的耦合性太强,可以将其分离出去。
创建一个AuthService,在src中新建一个叫做core的文件夹(src\app\core),然后命令行中输入 ng g s core\auth
然后为这个service添加一个方法:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor() { }
loginWithCredentials(username:string, password:string) : boolean {
if(username === '111'){
return true;
}
return false;
}
}
然后就可以在组件中调用这个service种的方法来使用了。
在login.component.ts中import引入AuthService,在构造函数中初始化service,在Login中调用service:
import { Component, OnInit } from '@angular/core';
import { AuthService} from '../core/auth.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
})
export class LoginComponent implements OnInit {
// 声明成员变量,其类型直接为AuthService
service: AuthService;
constructor() {
this.service = new AuthService;
}
ngOnInit() {
}
title='haha';
Login(username,password){
console.log('auth result is: '+ this.service.loginWithCredentials(username,password));
}
}
这种做法存在以下几个问题:
由于实例化是在组件中进行的,如果更改service的构造函数,组件也需要更改。
如果以后需要开发、测试、生成环境配置不同的AuthService,以这种方式实现会非常不方便。
Angular提供了一种依赖性注入(Dependency Injection)的方法。
下面使用DI来完成service的调用:
首先,需要在组件的修饰器中配置AuthService,然后在组件的构造函数中使用参数进行依赖注入:
import { Component, OnInit} from '@angular/core';
import { AuthService} from '../core/auth.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
// 在providers中配置AuthService
providers: [AuthService],
})
export class LoginComponent implements OnInit {
// 在构造函数中将AuthService实例注入到成员变量service中
// 而且不再需要显示地声明成员变量service了
constructor(private service: AuthService) {
}
ngOnInit() {
}
title='haha';
Login(username,password){
console.log('auth result is: '+ this.service.loginWithCredentials(username,password));
}
}
这种方式仍然需要在组件上方import相关服务:
import { AuthService} from '../core/auth.service';
import将类型引入进来,provider里配置这个类型的实例。
既然要用依赖注入,那么可不可以不引入AuthService?
在app.module.ts这个根模块文件中发现也有一个providers,根模块这个providers是配置在模块中全局可用的service或参数的:
providers: [
{provide:'auth', useClass:AuthService}
],
providers是一个数组,把想要注入到其他组件中的服务配置在这里。
可以看到,这个写法与上面的不同。
providers: [AuthService],
{provider:'auth',useClass:AuthService}
数组中填入的是一个对象,两个属性。provider定义了这个服务的名称,有需要注入这个服务的就引用这个名称就好。useClass指明这个名称对应的服务是一个类。这样定义好了之后,就可以在任意组件中注入这个依赖了。
接下来就可以去掉组件中头部的import部分,还有组件修饰器·中的providers.
并更改其构造函数为:
constructor(@Inject('auth') private service) {
}
去掉了service的类型声明,但加了一个修饰符@Inject('auth'),这个修饰符的意思就是到系统配置中找到名称为auth的那个依赖注入到修饰变量service中去。当然,需要在头部引入这个修饰符。
import { Component, OnInit, Inject } from '@angular/core';
完整代码如下:
import { Component, OnInit, Inject } from '@angular/core';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
})
export class LoginComponent implements OnInit {
constructor(@Inject('auth') private service) {
}
ngOnInit() {
}
title='haha';
Login(username,password){
console.log('auth result is: '+ this.service.loginWithCredentials(username,password));
}
}
评论