帶你瞭解Angular中的元件通訊和依賴注入

2021-09-22 13:01:41
元件間怎麼進行通訊?依賴注入是什麼?下面本篇文章帶大家簡單瞭解一下元件通訊的方法,並介紹一下依賴注入,希望對大家有所幫助!

1. 元件通訊

1.1 向元件內部傳遞資料

<app-favorite [isFavorite]="true"></app-favorite>
// favorite.component.ts
import { Input } from '@angular/core';

export class FavoriteComponent {
    @Input() isFavorite: boolean = false;
}

注意:在屬性的外面加 [] 表示繫結動態值,在元件內接收後是布林型別,不加 [] 表示繫結普通值,在元件內接收後是字串型別。【相關教學推薦:《》】

1.2 元件向外部傳遞資料

需求:在子元件中通過點選按鈕將資料傳遞給父元件

<!-- 子元件模板 -->
<button (click)="onClick()">click</button>
// 子元件類
import { EventEmitter, Output } from "@angular/core"

export class FavoriteComponent {
  @Output() change = new EventEmitter()
  onClick() {
    this.change.emit({ name: "張三" })
  }
}
<!-- 父元件模板 -->
<app-favorite (change)="onChange($event)"></app-favorite>
// 父元件類
export class AppComponent {
  onChange(event: { name: string }) {
    console.log(event)
  }
}

2. 依賴注入

2.1 概述

依賴注入 ( Dependency Injection ) 簡稱DI,是物件導向程式設計中的一種設計原則,用來減少程式碼之間的耦合度

class MailService {
  constructor(APIKEY) {}
}

class EmailSender {
  mailService: MailService
  constructor() {
    this.mailService = new MailService("APIKEY1234567890")
  }

  sendMail(mail) {
    this.mailService.sendMail(mail)
  }
}

const emailSender = new EmailSender()
emailSender.sendMail(mail)

EmailSender 類執行時要使用 MailService 類,EmailSender 類依賴 MailService 類,MailService 類是 EmailSender 類的依賴項。

以上寫法的耦合度太高,程式碼並不健壯。如果 MailService 類改變了引數的傳遞方式,在 EmailSender 類中的寫法也要跟著改變

class EmailSender {
  mailService: MailService
  constructor(mailService: MailService) {
    this.mailService = mailService;
  }
}
const mailService = new MailService("APIKEY1234567890")
const emailSender = new EmailSender(mailService)

在範例化 EmailSender 類時將它的依賴項通過 constructor 建構函式引數的形式注入到類的內部,這種寫法就是依賴注入。

通過依賴注入降了程式碼之間的耦合度,增加了程式碼的可維護性。MailService 類中程式碼的更改再也不會影響 EmailSender

2.2 DI 框架

Angular 有自己的 DI 框架,它將實現依賴注入的過程隱藏了,對於開發者來說只需使用很簡單的程式碼就可以使用複雜的依賴注入功能。

AngularDI 框架中有四個核心概念:

  • Dependency:元件要依賴的範例物件,服務範例物件

  • Token:獲取服務範例物件的標識

  • Injector:注入器,負責建立維護服務類的範例物件並向元件中注入服務範例物件。

  • Provider:設定注入器的物件,指定建立服務範例物件的服務類和獲取範例物件的標識。

2.2.1 注入器 Injectors

注入器負責建立服務類範例物件,並將服務類範例物件注入到需要的元件中

  • 建立注入器

    import { ReflectiveInjector } from "@angular/core"
    // 服務類
    class MailService {}
    // 建立注入器並傳入服務類
    const injector = ReflectiveInjector.resolveAndCreate([MailService])
  • 獲取注入器中的服務類範例物件

    const mailService = injector.get(MailService)
  • 服務範例物件為單例模式,注入器在建立服務範例後會對其進行快取

    const mailService1 = injector.get(MailService)
    const mailService2 = injector.get(MailService)
    
    console.log(mailService1 === mailService2) // true
  • 不同的注入器返回不同的服務範例物件

    const injector = ReflectiveInjector.resolveAndCreate([MailService])
    const childInjector = injector.resolveAndCreateChild([MailService])
    
    const mailService1 = injector.get(MailService)
    const mailService2 = childInjector.get(MailService)
    
    console.log(mailService1 === mailService2) // false
  • 服務範例的查詢類似函數作用域鏈,當前級別可以找到就使用當前級別,當前級別找不到去父級中查詢

    const injector = ReflectiveInjector.resolveAndCreate([MailService])
    const childInjector = injector.resolveAndCreateChild([])
    
    const mailService1 = injector.get(MailService)
    const mailService2 = childInjector.get(MailService)
    
    console.log(mailService1 === mailService2) // true

2.2.2 提供者 Provider

  • 設定注入器的物件,指定了建立範例物件的服務類和存取服務範例物件的標識

    const injector = ReflectiveInjector.resolveAndCreate([
      { provide: MailService, useClass: MailService }
    ])
  • 存取依賴物件的標識也可以是字串型別

    const injector = ReflectiveInjector.resolveAndCreate([
      { provide: "mail", useClass: MailService }
    ])
    const mailService = injector.get("mail")
  • useValue

    const injector = ReflectiveInjector.resolveAndCreate([
      {
        provide: "Config",
        useValue: Object.freeze({
          APIKEY: "API1234567890",
          APISCRET: "500-400-300"
        })
      }
    ])
    const Config = injector.get("Config")

將範例物件和外部的參照建立了鬆耦合關係,外部通過標識獲取範例物件,只要標識保持不變,內部程式碼怎麼變都不會影響到外部

更多程式設計相關知識,請存取:!!

以上就是帶你瞭解Angular中的元件通訊和依賴注入的詳細內容,更多請關注TW511.COM其它相關文章!