1. 程式人生 > >angular4架構概述(二)

angular4架構概述(二)

簡介

由angular的cli(腳手架)創建出來的專案可知,angular專案由模組(module)構建成,每個angular應用都至少有一個根模組,通常我們預設為AppModule模組。然後每個模組由元件+服務組成。

目錄

  1. angular模組分析
  2. angular元件分析
  3. angular服務分析
angular模組分析

angular模組是由裝飾器@ngModule來修飾,裡面包含的元資料有:

  1. declarations 宣告本模組所用到的元件,管道以及指令
  2. imports 引入本模組需要的其他模組
  3. providers 全域性模組的服務建立器,註冊之後,在任何模組都可以使用
  4. bootstrap 應用的主檢視,只有根模組才需要使用。也就是程式的主入口宣告模組
  5. exports 匯出本模組的元件可供給其他模組使用

通常我們建立專案預設的根模組在app.module.ts檔案中,引導這個根模組就可以啟動我們自己的應用了。
如圖:
這裡寫圖片描述
注:exports屬性一般不會匯入根元件(AppComponent),因為其它模組永遠不需要匯入根模組。

angular元件分析

angular元件元件是由裝飾器@Component來修飾,裡面包含的元資料物件屬性有:

  1. selector css的選擇器,一旦在html中找到所對應的標籤,就會例項化該元件。
  2. templateUrl 顯示元件檢視頁面HTML的所在位置。
  3. styleUrls 顯示元件檢視樣式的地址。
  4. providers 當前元件所需的依賴注入提供商的資料

如圖:
這裡寫圖片描述

注:你還可以用 template 屬性的值來提供內聯的 HTML 模板。 這個模板定義了該元件的宿主檢視。

  template : `<h1>hello</h1>
               <div>...</div>`
angular服務分析

angular把元件和服務給分離開是為了程式更好的擴充套件性,以及複用性,服務由裝飾器@Injectable修飾。

如圖:
這裡寫圖片描述
圖中建立了一個LoggerService服務,其中用@Injectable所修飾。那麼我們可以在元件中來呼叫該服務:
1.首先我們在app.component.html建立3個按鈕,構造它們的點選事件:

<button (click)="onclik(1)">提示</button>
<button (click)="onclik(2)">提示1</button>
<button (click)="onclik(3)">提示2</button>

注:(click)在angular中屬於點選事件。
2.我們繼續在app.component.ts的構造方法傳入該service:

@Component({
  selector: 'app-root',//css的選擇器,一旦在html中找到所對應的標籤,就會例項化該元件。
  templateUrl: './app.component.html',//該元件檢視頁面HTML的地址。
  styleUrls: ['./app.component.css'],//該元件檢視樣式的地址.
  providers: []//當前元件所需的依賴注入提供商的資料
})
export class AppComponent{

  constructor(private service:LoggerService) {
  }
  onclik(data: number) {
    if (data === 1) {
      this.service.log("log");
    } else if (data === 2) {
      this.service.warn("warn");
    } else if (data === 3) {
      this.service.error("error");
    }
  }
}

如果用上面方式開啟ng serve開啟專案會報以下錯誤:

AppComponent_Host.ngfactory.js? [sm]:1 ERROR Error: StaticInjectorError(AppModule)[AppComponent -> LoggerService]: 
  StaticInjectorError(Platform: core)[AppComponent -> LoggerService]: 
    NullInjectorError: No provider for LoggerService!
    at _NullInjector.get (core.js:1002)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.get (core.js:1110)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.get (core.js:1110)
    at resolveNgModuleDep (core.js:10854)
    at NgModuleRef_.get (core.js:12087)
    at resolveDep (core.js:12577)

上述錯誤是我們沒有在provider中注入LoggerService,我們應該把所有的服務中注入到provider中,在這裡程式啟動會自動幫我們例項化該服務物件。

修改之後:

@Component({
  selector: 'app-root',//css的選擇器,一旦在html中找到所對應的標籤,就會例項化該元件。
  templateUrl: './app.component.html',//該元件檢視頁面HTML的地址。
  styleUrls: ['./app.component.css'],//該元件檢視樣式的地址.
  providers: [LoggerService]//當前元件所需的依賴注入提供商的資料
})

這裡寫圖片描述

@Injectable()

@Injectable()修飾器是否必須要?
首先我們把上面LoggerService中的修飾器@Injectable刪除之後,發現程式依舊可以執行起來。

猜想:LoggerService是獨立執行起來的,根本沒有依賴別的物件,相當於一個簡單的類。那我們試試在LoggerService注入別的Service看看。

新建一個Service:

export class HeroService {
  heros: { id: number; name: string } =
    { id: 11, name: 'Mr. Nice' }
  getHeros() {
    return this.heros;
  }
}
import { Injectable } from '@angular/core';
import { HeroService } from './hero.service';

export class LoggerService {

  constructor(heroService:HeroService){

  }

  log(msg: any)   { console.log(msg); }
  error(msg: any) { console.error(msg); }
  warn(msg: any)  { console.warn(msg); }
}

這次我們在LoggerService中沒有新增@Injectable(),在構造方法傳入HeroService,然後把HeroService注入到Provider中避免出現上面錯誤。執行程式:

compiler.js:485 Uncaught Error: Can't resolve all parameters for LoggerService: (?).
    at syntaxError (compiler.js:485)
    at CompileMetadataResolver._getDependenciesMetadata (compiler.js:15700)
    at CompileMetadataResolver._getTypeMetadata (compiler.js:15535)
    at CompileMetadataResolver._getInjectableMetadata (compiler.js:15515)
    at CompileMetadataResolver.getProviderMetadata (compiler.js:15875)
    at eval (compiler.js:15786)
    at Array.forEach (<anonymous>)
    at CompileMetadataResolver._getProvidersMetadata (compiler.js:15746)
    at CompileMetadataResolver.getNonNormalizedDirectiveMetadata (compiler.js:15007)
    at CompileMetadataResolver._getEntryComponentMetadata (compiler.js:15848

上面異常資訊說明無法解析 LoggerService的所有引數,加上@Injectable之後專案可以執行起來。

總結:

@Injectable() 是必須的麼?

如果所建立的服務不依賴於其他物件,是可以不用使用 Injectable 類裝飾器。但當該服務需要在建構函式中注入依賴物件,就需要使用 Injectable 裝飾器。不過比較推薦的做法不管是否有依賴物件,在建立服務時都使用 Injectable 類裝飾器。

相關推薦

angular4架構概述

簡介 由angular的cli(腳手架)創建出來的專案可知,angular專案由模組(module)構建成,每個angular應用都至少有一個根模組,通常我們預設為AppModule模組。然後每個模組由元件+服務組成。 目錄 angular模

[轉]畢設- 深入HBase架構解析

node 角度 發送 under 收集 .org fig 服務器 url 深入HBase架構解析(二) 前言 這是《深入HBase架構解析(一)》的續,不多廢話,繼續。。。。 HBase讀的實現 通過前文的描述,我們知道在HBase寫時,相同Cell(RowKe

一起寫框架-控制反轉Ioc概述

val 程序設計 log font 修改 style 編程思想 調用方法 cal 控制反轉概述 控制反轉(Inversion of Control,英文縮寫為IoC),就是將代碼的調用的控制權,由調用方轉移給被調用方。 如圖:修改代碼A類的代碼,才能將B類的對象換成C類

從0開始的微服務架構如何快速體驗微服務架構

常常 原來 人員 google tty 打包 第三方 江湖 ces 雖然已經紅了很久,但是“微服務架構”正變得越來越重要,也將繼續火下去。各個公司與技術人員都在分享微服務架構的相關知識與實踐經驗,但我們發現,目前網上的這些相關文章中,要麽上來就是很有借鑒意義的幹貨,要麽就是

InnoDB體系架構總結

原子性 val 新版本 insert logfile net row syn 數據頁 事務 確保事務內的SQL都可以同步執行 要麽一起成功 要麽一起失敗。事務有四個特性原子性 一致性,隔離性,持久性 實現方式 開始事務的時候回家記錄記錄一個LSN日誌序列 當事務執行的時候

微服務架構 SpringCloudEureka服務註冊和服務發現基礎篇

col false -c conf gis 功能 pri desc sch 一:Eureka簡介 Eureka是Spring Cloud Netflix的一個子模塊,也是核心模塊之一。用於雲端服務發現,一個基於REST的服務,用於定位服務,以實現雲端中間層服務發現和故障轉移

ABP總體介紹 - 層架構體系

html wcf log 領域驅動 cat spa inf 前端框架 發送郵件 1.2 ABP總體介紹 - 層架構體系 1.2.1 前言 為了減少復雜性和提高代碼的可重用性,采用分層架構是一種被廣泛接受的技術。為了實現分層的體系結構,ABP遵循DDD(領域驅動設計)的原則,

NetCore+Dapper WbpApi架構搭建:底層封裝

isnull lis sel .sql click defaults cts 數據庫 redis 看下我們上一節搭建的架構,現在開始從事底層的封裝 1、首先需要一個實體的接口IEntity 1 namespace Dinner.Dapper 2 { 3

電商系統架構總結

esp 簡單 zed expire cts project scac 允許 類型 二 Redis緩存 考慮到將來服務器的升級擴展,使用redis代替.net內置緩存是比較理想的選擇。redis是非常成熟好用的緩存系統,安裝配置非常簡單,直接上官網下載安裝包 安裝啟動就行

『中級篇』容器的技術概述

都在 部署 擴展 統一 之間 解決方案 src 物理 環境 容器的前世今生 ###物理機 部署非常慢購買服務器服務,放在IDC機房,各種走流程,很多流程不可控制流程慢。 成本非常高物理的服務器,高額的配置成本貴。 資源浪費資源太多了,針對app的服務可能利用率不夠充分。

J2EE WEB應用架構分析

高可用 XML 控制 之間 財務 環境 優缺點 基於 list 優缺點 優點: 一些開發商開始采用並推廣這個框架 作為開源項目,有很多先進的實現思想 對大型的應用支持的較好 有集中的網頁導航定義 缺點: 不是業屆標準 對開發工具的支持不夠 復雜的taglib,需要比較長的時

搭建LNMP架構論壇

ges images conf all file blog 組件 規則 tex 配置nginx(1)關閉防火墻,並保存規則(2)cd到/usr/local/src目錄下(3)解壓xzvf pcre-8.35.tar.gz文件(4)cd到pcre-8.35編譯生成安裝組件.

spring AOP 概述 Pointcut

分享圖片 圖片 mat 方法名 end 方法 hat color pointcut   Pointcut(切點)決定Advice通知應該作用於哪個連接點,也就是說通過Pointcut來定義需要增強的方法 的集合,這些集合的選取可以按照一定的規則來完成。在這種情況下,Poin

Java EE入門教程系列第一章Java EE的概述——Java EE技術框架和開發工具

1.3Java EE的技術框架 從技術的角度劃分,完整的Java EE分成了4個部分:元件技術、服務技術、通訊技術和架構技術。 下面給出的是一個適合初學者的體系結構簡化圖,暫時接觸不到的部分統一用“支援技術”表示,我們暫時只專注於與應用級開發相關的技術即可。 1.元件技術 這是

從招式與內功談起——設計模式概述

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Java架構-JavaSE之繼承、封裝、多型

閱讀目錄(Content) 一、封裝(資料的隱藏)   1.1、封裝的步驟   1.2、舉例   1.3、封裝的作用   1.4、封裝的意義 二、方法的過載 三、繼承 四、super關鍵字   4.1、super的使用   4.2、super使用的注意的地方   4.3、super

javascript 簡要概述

javascript面向物件 javascript竟然也可以面向物件,厲害了。在javascript中建立物件是這樣的 function foo(n){ this.name =n; } var obj=new foo("ww"); console.log(obj.name); //輸

架構探險:DBUtils簡單使用

繼續我們的冒險體驗,之前綜述了一些構建一個專案的大致流程,相信大家對於系統的框架已經瞭然於胸。 今天我們就來談一談,如何構建資料的橋樑。 這裡我們使用commons-dbutils 來簡單的封裝一個jdbc template, 幫助我們實現快速的CRUD. 廢話不多講直接上程式碼。

TesseractOCR光學字元識別引擎概述

目錄 四、單詞識別(Word Recognition) 五、形狀分類器( Shape Classification) 六、分詞與檢索(Segmentation and Search) 七、自適應分類器 (adaptive classifier) 四、單詞識

基於Maven的SSM總體架構設計

3 總體設計 3.1 約定 3.1.1 基於Maven的工程結構         為了便於本團隊對新建Java專案的工程結構及依賴庫(jar)的版本統一,降低團隊成員之間的溝通成本,減少因依賴庫版本不一致導致的異常,我們約定建立標準的Maven工程。即在MyE