如何在不同组件中获取数据服务?

时间:2017-09-12 14:53:38

标签: angular typescript

对不起我的英语如果非常糟糕,我来自俄罗斯。我想要问你。请帮帮我吧。 我有角度4的服务,我如何在许多组件中管理它?

这是我的服务:

import {EventEmitter, Injectable} from '@angular/core';

@Injectable()
export class AuthService {
    status: boolean = false;
    userAuth: EventEmitter<boolean> = new EventEmitter();
    auth() {
      this.status = true;
      this.userAuth.emit(this.getAuth());
    }
    logout() {
      this.status = false;
      this.userAuth.emit(this.getAuth())
    }
    getAuth() {
      return this.status;
    }
}

这是我的第一个组件。我已经订阅了ngOnInit中的服务

import {Component, OnInit} from '@angular/core';
import {ApiService} from "../../service/api/api.service";
import {BlockUI, NgBlockUI} from 'ng-block-ui'
import {AuthService} from "../../service/auth/auth.service";

@Component({
    selector: 'app-header',
    templateUrl: './header.component.html',
    styleUrls: ['./header.component.less'],
    providers: [ApiService, AuthService]
})
export class HeaderComponent implements OnInit {
    isLogin: boolean = false;
    @BlockUI() blockUI: NgBlockUI;
    constructor(private as: ApiService, public authService: AuthService) {
      this.blockUI.start();
      this.as.isLogin().then((res) => {
        if (res.hasError()) return false;
        if (res.getResponse().login) this.authService.auth();
        if (!res.getResponse().login) this.authService.logout();
        // this.isLogin = this.authService.getAuth();
        this.blockUI.stop();
      });
    }
    ngOnInit() {
      this.authService.userAuth.subscribe((status) => {
        this.isLogin = status;
        console.log('status', status);
        console.log('this.isLogin', this.isLogin);
      })
    }
    logout() {
      this.as.logout().then((res) => {
        if (res.hasError()) return false;
        this.authService.logout();
        // this.isLogin = this.authService.getAuth();
      });
    }
}

但如果在另一个组件中调用该服务,它将调用新服务。

import {Component, EventEmitter, OnInit, Output} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from "@angular/forms"
import {ApiService} from "../../service/api/api.service";
import {AuthService} from "../../service/auth/auth.service";

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.less'],
  providers: [ApiService, AuthService]
})
export class LoginComponent {
  formLogin: FormGroup;

  constructor(private fb: FormBuilder, private as: ApiService, public authService: AuthService) {
    this.formLogin = fb.group({
      email: [null, Validators.compose([Validators.required, Validators.pattern(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)])],
      password: [null, Validators.compose([Validators.required, Validators.minLength(6)])]
    });
  }

  auth(form) {
    this.as.authUser(form).then(res => {
      if (res.hasError()) return false;
      this.formLogin.reset();
      this.authService.auth();
    });
  }
}

2 个答案:

答案 0 :(得分:1)

对于每个组件,您都会收到一个新的AuthService实例,因为您在两个组件提供程序中都提供了AuthService类。

Angular2依赖注入(DI)或多或少地以下列方式工作:

  • 每个组件都有其注入器及其提供者
  • 当你要求DI为你提供它在其提供者中检查的东西的实例时,如果它在那里找到“配方”,它会创建一个实例,将其放入其注入器并按要求提供
  • 如果它的提供者中没有找到“配方”并且它的注入器中的实例没有找到,那么同样的请求被提升到它的父亲那里,而父亲又将检查其提供者的“配方”或其注入现有实例
  • 当进入这个分层链(直到主模块)时,它会找到所请求令牌的提供者,该实例将被创建并按要求返回
  • 从那时起,具有请求实例的注入器的组件的所有子节点将以单例形式接收该实例。

因此,回到您的具体问题,您将收到两个不同的AuthService实例,因为两个组件都包含其“配方”,因此它们都创建一个实例,将其保存在其注入器中并在请求时返回它DI。

要解决您的问题,您可以:

  • 从每个组件的装饰器元数据中删除AuthService的提供程序
  • 将AuthService添加到模块装饰器元数据中的提供程序。

__

@Component({
    selector: 'app-header',
    templateUrl: './header.component.html',
    styleUrls: ['./header.component.less'],
    providers: [ApiService]
})
export class HeaderComponent implements OnInit { /* ... */ }

__

@Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.less'],
    providers: [ApiService]
})
export class LoginComponent { /* ... */ }

在主模块声明中

@NgModule({
    imports: [ /* ... */ ],
    declarations: [ /* ... */ ],
    providers: [AuthService, OtherServices],
})

答案 1 :(得分:0)

您需要将其添加到主模块中,因为angular会创建单件服务对象,如果您在组件级别提供服务,则服务实例将仅特定于您的特定组件,但您无法在组件之间共享服务数据。因此,您需要在主模块中提供它以在组件之间共享。

$input_submit删除服务提供商,然后将服务注入$data @Component

component's