发表于: 2020-01-03 21:19:42

1 1377


今日完成:


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:stringpassword:string) : boolean {
    if(username === '111'){
      return true;
    }
    return false;
  }
}



然后就可以在组件中调用这个service种的方法来使用了。

在login.component.ts中import引入AuthService,在构造函数中初始化service,在Login中调用service:

import { ComponentOnInit } from '@angular/core';
 import { AuthServicefrom '../core/auth.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],

})
export class LoginComponent implements OnInit {

  // 声明成员变量,其类型直接为AuthService
  serviceAuthService;

  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 { ComponentOnInitfrom '@angular/core';
 import { AuthServicefrom '../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 serviceAuthService) {
   }

  ngOnInit() {
  }

  title='haha';
  Login(username,password){
    console.log('auth result is: 'this.service.loginWithCredentials(username,password));
  }


}


这种方式仍然需要在组件上方import相关服务:

 import { AuthServicefrom '../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 { ComponentOnInitInject } from '@angular/core';


完整代码如下:

import { ComponentOnInitInject } 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));
  }

}



返回列表 返回列表
评论

    分享到