这个Angular 2应用程序中的服务层次结构究竟如何工作?

时间:2017-08-07 14:18:35

标签: javascript angular angular2-services javascript-framework

我是 Angular 2 中的新手,我对服务有以下疑问。

进入主视图(与 app.component.ts 类相关的视图)我遇到这种情况:

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-md-8 col-md-offset-2">
      <app-new-account (accountAdded)="onAccountAdded($event)"></app-new-account>
      <hr>
      <app-account
        *ngFor="let acc of accounts; let i = index"
        [account]="acc"
        [id]="i"
        (statusChanged)="onStatusChanged($event)"></app-account>
    </div>
  </div>
</div>

因此,在此视图中,我有2个子组件( app-new-account app-account )。

进入主 AppComponent 组件类我:

import {Component, OnInit} from '@angular/core';
import {AccountsService} from './accounts.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [AccountsService]
})
export class AppComponent implements OnInit {

  accounts: {name: string, status: string}[] = [];

  // Injectiong the AccountsService:
  constructor(private accountsService: AccountsService) {}

  ngOnInit() {
    this.accounts = this.accountsService.accounts;
  }

}

我将 AccountsService 定义为此行的服务到组件装饰器中:

providers: [AccountsService]

根据我的理解,它指定此类 AccountsService 必须注册为 AppComponent 主要组件的服务,注册为其所有子组件 STRONG>。是这个断言是真的还是我错过了什么?

因此,这意味着与之前的 app-new-account app-account 标记相关的两个子组件类共享的相同实例AccountsService 类作为服务?

这是什么原因,因为在这两个子组件的提供商数组中,我没有 AccountsService

我的理由是正确还是我错过了什么?

1 个答案:

答案 0 :(得分:5)

  

所以,这意味着两个子组件类相关   之前的app-new-account和app-account标签共享同一个实例   AccountsService类作为服务?

是。每个组件实例创建一个注入器。由于注入器是分层的,因此组件的所有子节点都访问与父节点相同的服务实例。 除非,否则他们使用相同的令牌在自己的providers数组中定义服务。这是喷射器的图表:

// all components share the same instance
     AppComponentInjector
  providers: [AccountsService]
       /               \
      /                 \
 app-new-account     app-account
    // app-new-account has its own instance
             AppComponentInjector
          providers: [AccountsService]
           /                     \
          /                       \
   app-new-account                 app-account
   providers: [AccountsService]
     // every component has its own instance
         AppComponentInjector
      providers: [AccountsService]
       /                           \
      /                             \
  app-new-account                   app-account
  providers: [AccountsService]      providers: [AccountsService]

主机元素

我还会提供更多细节,因为我认为其他地方没有明确解释。注入器是在组件/指令主机元素上创建的。这意味着指令在它所放置的主机元素上创建自己的注入器。

因此,如果您在hr模板的AppComponent元素上添加了包含提供程序的指令:

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-md-8 col-md-offset-2">
      <app-new-account (accountAdded)="onAccountAdded($event)"></app-new-account>
      <hr somedirectivewithproviders>  <----------------

您将拥有以下层次结构:

  // all components and directives share the same instance
                AppComponentInjector
            providers: [AccountsService]
        /               |                  \
       /                |                   \
app-new-account somedirectivewithproviders   app-account

这意味着如果somedirectivewithproviders定义AccountsService并注入它,它将获得新实例作为组件。但组件仍将从AppComponentInjector

获取实例
  // all components and directives share the same instance
                    AppComponentInjector
                 providers: [AccountsService]
        /                      |                    \
       /                       |                     \
// gets same instance   //gets new own instance      // gets same instance   
 app-new-account      somedirectivewithproviders     app-account
                      providers: [AccountsService]