【问题标题】:Why do my Angular Services work without specifying them in the provider argument of the @Component annotation?为什么我的 Angular 服务没有在 @Component 注释的提供者参数中指定它们就可以工作?
【发布时间】:2020-05-25 07:12:48
【问题描述】:

我正在学习 Udemy 的 Angular 课程,老师说我们需要在 @Component 注释的提供程序部分指定我们要导入的服务,以告诉 Angular 需要在该组件中注入哪些服务。但是我的组件在没有指定的情况下可以正常工作。

这是为什么呢?

这是我的组件

import { Component, EventEmitter, Input, Output } from '@angular/core';
import {AccountService} from "../services/account-service";

@Component({
  selector: 'app-account',
  templateUrl: './account.component.html',
  styleUrls: ['./account.component.css']
})
export class AccountComponent {
  @Input() account: {name: string, status: string};
  @Input() id: number;

  constructor(private accountService:AccountService) {
  }

  onSetTo(status: string) {
    this.accountService.updateStatus(this.id,status);
  }
}

这就是服务

import { Injectable } from '@angular/core';
import {LoggingService} from "./logging.service";

@Injectable({
  providedIn: 'root'
})
export class AccountService {
  accounts = [
    {
      name: 'Master Account',
      status: 'active'
    },
    {
      name: 'Testaccount',
      status: 'inactive'
    },
    {
      name: 'Hidden Account',
      status: 'unknown'
    }
  ];
  constructor(private loggingService: LoggingService) { }

  addAccount(name:string, status:string){
    this.accounts.push({name:name, status:status})
    this.loggingService.logStatusChanged(status)
  }

  updateStatus(id:number,status:string){
    this.accounts[id].status = status;
    this.loggingService.logStatusChanged(status)
  }
}

【问题讨论】:

  • 如果服务包含在AppModule 中或像您的示例一样使用providedIn: 'root',那么它就是singleton service。在整个应用程序中只有一个实例,并且对所有组件都可用。

标签: angular angular9


【解决方案1】:

由于 providedIn: 'root' 从 Angular 6 开始可用,它可以工作,这告诉 Angular 在应用程序根目录中提供服务,以便在您的组件上可用。如果您要使用的服务是特定于组件的,那么您可以在组件级别专门提供它。

【讨论】:

    【解决方案2】:

    提供服务的方式多种多样。

    由于您的服务在 @Injectable 装饰器中 providedIn: root,因此它在您的应用程序的根目录中可用,因此您无需在其他地方引用它你需要访问它的实例。在这种情况下,您不需要在模块或组件中提供它。

    【讨论】:

      【解决方案3】:

      服务之所以有效,是因为有两种方法可以使服务可用,在这种情况下,您在服务定义中定义了 providedIn。

      @Injectable({
        providedIn: 'root'
      }) 
      

      两种方式分别是:

      1. 将@Injectable() 的providedIn 属性设置为“root”。

      2. 将服务包含在 AppModule 或仅由 AppModule 导入的模块中。

      您的代码中已经有第一个解决方案,我将说明第二种情况。

      app.module.ts

      @NgModule({
        ...
        providers: [AccountService],
        ...
      })
      

      我希望这可以帮助您理解它为什么起作用。

      祝你好运!!!

      【讨论】:

        【解决方案4】:

        如果您使用@Injectable({providedIn: 'root'}) 创建一个服务,它代表一个单例服务服务,在整个应用程序中只有一个实例。

        如果你创建一个没有@Injectable({providedIn: 'root'})的服务,它代表一个共享服务。所以为了在你的组件中注入一个共享服务,你在那个特定组件的@Component装饰器中提到它。

        这样,您的组件可以创建服务类的新实例并访问其方法/变量,并且它将在您的组件范围内。

        【讨论】:

          【解决方案5】:

          在 Angular 中,您可以分 3 个级别注入服务

          • Root - 默认情况下为单例
          • 模块 - 如果在模块外部声明并在模块之间共享,这也类似于根级别注入,@Injectable({providedIn: 'platform'})@Injectable({providedIn: 'any'}) 无效很高兴被告知其他情况
          • 组件 - 这是创建每个组件的服务实例的完整瞬态行为

          参考下面的例子

          https://stackblitz.com/edit/angular-ivy-dvrhef

          【讨论】:

            猜你喜欢
            • 2020-06-23
            • 2019-11-20
            • 2017-08-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-08-17
            相关资源
            最近更新 更多