2017 年 3 月

第 32 卷,第 3 期

本文章是由機器翻譯。

程式設計師雜談 - 如何使用 MEAN: Angular 元件

Ted Neward | 2017 年 3 月

Ted Neward歡迎回來,MEANers。

上個月我開始我下降到 Angular — 它,看看一些較明顯的組件構成簡單角度"Hello World"應用程式與基底範本中,使用快速入門 (msdn.com/magazine/mt793274)。很顯然 Angular (先前稱為 Angular 2) 會採用稍微不同的方法,來建置單一頁面應用程式 (Spa) 比其他許多 JavaScript Web 架構,包括其立即前置項 AngularJS (之前稱為角度 1)。但這些差異並不是開放原始碼 peevishness 在想要只是為了這麼做有不同; 不同方式執行的結果建置 Web 應用程式的新方法建置 groundswell 有興趣,而且 Angular 已選擇使用這兩個手上抓取。

新是網站的 「 元件 」。

元件

有兩種方式可以思考文字元件。其中一個是細分的主要部分組成的傳統角度的應用程式。該清單是比較短,類似於 Angular 或其他 Web 架構︰

  • 模組
  • 元件
  • 服務
  • 路由

幾個其他部分仍然潛伏在角度的世界裡,但大多數的情況下,這些是四個主要元件組成角度的應用程式。

模組是最上層的隔離和 cognition 單位。基本上,數個模組會構成應用程式,其中的模組是較小的部分 (元件、 服務等) 合理地結合群組周圍的容器。模組通常通常是部署單位,這是什麼瀏覽器便會下載到使用者的電腦才能執行。更重要的是,它們只是單位認知分隔的.NET 組件是相同的方式。開發人員與系統的所有程式碼、 資源和其他相關的資產,屬於 「 檢視與顯示目前的時間 」 會一起分組到單一的 「 時間 」 模組,如果不需要思考時間,除非正在使用 (或) 該模組。

這可減少開發人員想要追蹤的系統中移動的組件的整體認知負載。很明顯地,開發人員可自行將所有項目放入單一模組中,很可能在一個.NET 組件中撰寫整個桌面應用程式一樣。不過,體驗其加強下任何數量的大部分開發人員會有一些對其中一個模組的程式行應該繪製,而且它們會據以模組化程式碼。(是否同意這些行所處,相反地,任何兩個開發人員是完全不同的故事)。

元件就像是模組,但較小的 writ — 其中一個模組可能包含所有定義的 HTTP 通訊 (例如 Angular 的 HttpModule) 或 HTML 表單 (FormsModule) 相關的事,元件是一般的單一用途和直接相關的 ui。在上個月的專欄 Hello World 應用程式,程式碼必須剛好只有一個元件 — AppComponent,其提供問候世界的簡單、 非互動式的文字顯示。雖然簡單,它是與此元件可用於更多或較不透明的方式,透過事實證明,是 full-blooded 角度元件,<my-app>提供為元件的標記的標記。</my-app>基本上,標記使用量會成為用戶端使用元件的 「 表面區域 」。

相反地,服務會比較像是通常可用來存取不應該是元件本身的一部分的基礎功能的低階程式庫。在角度方法中,通常會進行任何類型的 HTTP API 呼叫 (例如節點/Express/Mongo 後端的一年內 Microsoft 駭客出) 應該插入服務結合在一起,只要用所需要的元件。一般而言,會有較少的服務與元件中指定角度的應用程式,但是不用說,「 您的里程數可能會有所不同。 」

最後,為路由的瀏覽的主要機制。路由會定義傳入的 URL 模式的對應角度的應用程式應該如何回應。撰寫類似 Express.js 的路由傳送至的精神,路由會以方便參考同一個地方,從 「 路由對應 」 中定義而通常路由會對應到元件 (雖然該元件又可能 — 而且通常會 — 請使用其他元件的)。

這看起來似乎有點過度負荷,尤其是 word 「 元件 」,大量使用,但事實上,它是比表面看起來更簡單。首先藉由定義新的元件,請從 AppComponent 應用程式組件 (有時稱為 「 根元件 」 動作的開始處因為) 參考的顯示名稱和按鈕,按一下時,列印的名稱至主控台。它是一個簡單的元件,但它會做為簡單的方法,以了解如何建立新的元件,來參考它,然後用它。

GreetingsComponent

依照慣例,角度喜歡後置詞的任何元件類型的 word 「 元件 」,因為此元件設計來提供問候語,GreetingsComponent 看起來像是適當 — 如果無聊 — 它的名稱。它會存在於檔案,稱為 greetings.component.ts,但該檔案所在不自動的決策。有些角度的開發人員想要將每個元件放入自己的目錄,例如問候語或部分會將其放入元件目錄。相反地,當然就是一律只讓它向右 app.component.ts 旁邊。爭論範圍角度的開發人員對於優良的選項,但為了簡單起見,我們將會執行這 app.component.ts,等以 greetings.component.ts 存在直接在應用程式目錄中。

開啟片語是 greetings.component.ts 的非常類似於 AppComponent 從上一次︰

import { Component } from '@angular/core';
@Component({
  selector: 'greetings',
  template: '<div>Hello</div>'
})
export class GreetingsComponent {
}

它是其實只是簡單的標籤。不複雜,請參閱這裡。

不過,使用它,表示您可以接到 GreetingsComponent 到 AppComponent,使 AppComponent HTML 會包含它,就像這樣︰

@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1><greetings></greetings>`,
})
export class AppComponent  { name = 'Angular'; }

唯一的變更是在 [範本] 上的中繼資料 AppComponent。(我們可以找到更美好的即時之前太長,別擔心,您不打算在您元件的類別檔案中有大量的 HTML。)

不過,您可以儲存已修改的 app.component.ts,如果 Angular 會重新載入 (假設您執行 「 npm 開始 」,或仍在執行與上個月),並看到 「 Hello 」 訊息。這是因為 GreetingsComponent 還未載入,因此無法辨識 Angular<greetings>是 placeholding 元件的其中一個標記。</greetings>若要這樣做,請破解開啟應用程式會將模組檔案、 app.module.ts,並註冊您自己的其中一個 GreetingsComponent:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }  from './app.component';
import { GreetingsComponent } from './greetings.component';
@NgModule({
  imports:      [ BrowserModule ],
  declarations: [ AppComponent, GreetingsComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

唯一的變更是在 @NgModule 中繼資料裝飾 AppModule 類別中加入 「 匯入 」,以便在 GreetingsComponent 從磁碟,並將它登錄為 「 宣告 」。假設一切拼字正確,而檔案存在時,會顯示文字"Hello"。進度 !

不過,現在您需要進行一些變更,是元件本身 — 和這裡的重點是,所做的變更是元件,整齊地封裝,而不適用於任何其他項目。

加入屬性

首先,一般的"Hello"似乎無用的。讓我們將欄位加入 GreetingsComponent 来給予它至少某種程度的個人化︰

import { Component } from '@angular/core';
@Component({
  selector: 'greetings',
  template: '<div>Hello my name is {{name}}.'
})
export class GreetingsComponent {
  constructor() {
    this.name = 'Tarzan'
  }
}

當您儲存檔案時,您應該會看到 「 Hello 我的名字是 Tarzan 」 顯示。「 名稱 」 屬性是只有一個標準的 TypeScript 屬性 — nothing 神奇那里。

不過,那就天下太平了如果無法在外部,判斷名稱,而不是硬式編碼的類別為 「 Tarzan 」。 這是 @Input 屬性的角色︰

import { Component, Input } from '@angular/core';
@Component({
  selector: 'greetings',
  template: '<div>Hello my name is {{name}}.'
})
export class GreetingsComponent {
  @Input() name : string;
  constructor() { }
}

請注意兩件事︰ 首先,您強型別屬性的名稱,以便協助確保只有字串取得那里; 傳遞 TypeScript第二,@Input() 的註解前方。這會指示 Angular 屬性的實際資料應該來自於父元件,您現在看起來像是 app.component.ts 中修改的標記使用量︰

@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1><greetings name="Tarzan"></greetings>`,
})
export class AppComponent  { name = 'Angular'; }

請注意 「 名稱 」 多載。名稱是屬性,用於內部 AppComponent,但也 GreetingsComponent,屬性,這兩個是清楚分開。當然,如果從 AppComponent 的名稱傳遞到 GreetingsComponent 為目標,被藉由使用 {{name}} 插補繫結內 GreetingsComponent 的範本,而不是常值"Tarzan。 」

在許多情況下,傳遞至元件的輸入會是不是字串。在這些情況下,像這樣的屬性繫結的語法帶稍有不同的轉型,例如︰

<user-profile [user]="currentUser"></user-profile>

在這裡,[使用者] 屬性的非字串型別 (大概會類似使用者設定檔),且 currentUser 是目前已驗證的使用者。您稍後就會看到多個這種語法,當您開始使用非基本型別 (例如演講者備忘類別) 來保存元件所使用的資料。

加入方法

角度元件都是,其實只是 TypeScript 類別,因此很容易將新的方法加入至類別,諸如 「 執行某個動作,,"列印至主控台的名稱︰

@Component({
  selector: 'greetings',
  template: '<div>Hello my name is {{name}}.</div>'
})
export class GreetingsComponent {
  @Input() name : string;
  constructor() { }
  sayMyName() {
    console.log('My name is', this.name)
  }
}

SayMyName 方法會完全,只列印在瀏覽器主控台的 [名稱] 屬性。不過,通常這些方法會想要叫用透過使用者動作 — 也就是說,他們必須設定至瀏覽器事件,並且需要另一個,稍有不同,語法方法繫結至角度的事件,例如按一下按鈕。因此如果 GreetingsComponent 一部分的 HTML 範本定義的按鈕,然後可以繫結按鈕的 click 事件呼叫 sayMyName,就像這樣︰

@Component({
  selector: 'greetings',
  template: '<div>Hello my name is {{name}}.' +
    ' <button (click)="sayMyName()">Say my name</button></div>'
})
export class GreetingsComponent {
  @Input() name : string;
  constructor() { }
  sayMyName() {
    console.log('My name is', this.name)
  }
}

不同之處在於 Angular 堅持事件繫結必須 (讓它可以 (按一下),而不是 onClick) 括號; 事件繫結語法看起來類似於傳統的 HTML 事件繫結屬性繫結使用方括號,以及事件繫結使用循括號。它是有點奇怪,經過一段時間就變得更方便,但首先,查看和 dare 我很方便,因為現在符號會使它更加清楚這是屬性、 哪些是事件。

移除 HTML

如果想到住 TypeScript 程式碼內的 HTML 會覺得有點奇怪,元件可讓位於外部檔案的範本通常遵循以成行 component.ts component.html 的命名慣例。因此,比方說,如果 GreetingsComponent 想要保留其整個 HTML 獨立檔案中,它便會進入 greetings.component.html,且 @Component 上的中繼資料元件本身中使用 templateUrl 屬性參考︰

@Component({
  selector: 'greetings',
  templateUrl: './app/greetings.component.html'
})
export class GreetingsComponent {
  @Input() name : string;
  constructor() { }
  sayMyName() {
    console.log('My name is', this.name)
  }
}

請特別注意用於 templateUrl,因為它是相對於整個應用程式的根目錄,因此即使 greetings.component.html 位於 greetings.component.ts 的旁邊,必須從 「 應用程式 」 目錄的父參考的 HTML 檔案的 URL。

總結

Angular 的方法來建置 Web 應用程式會開始變得很清楚︰ 開發人員,應該定義較細微的元件,並接著將它們結合表單大規模的應用程式的各種方式。絕不是新的概念。事實上,它的日期回輝煌的 Visual Basic 3 和其他 freewheeling 工具的 ' 90s。角度小組只要有帶入網路世界裡,這些概念,並結合某些較新的工具,讓經驗,簡潔和更像 Web 式。當然,開發人員可以定義整個應用程式做為單一元件,但它不會發生之前嘗試執行這項操作的難題所獲得的大幅帶來 (若有的話,我相信不會有)。

大部分仍有完成工作,但某些路徑的開始,以便清楚︰ 如果此應用程式將會演講者的資料庫,則我們必須定義一些 SpeakerComponents,至少要顯示和編輯的演講來賓。後端通訊,都需要服務,或兩個。某些裝飾和其邊緣的燈號可能會漏掉了一些程式,然後一些擁有人可以使用某些 Url 的路由。停止回應,其實還有更多尚未準備。在此同時,祝各位寫程式 !


Ted Neward是西雅圖 polytechnology 顧問、 講師及指導。 他已寫入超過 100 個文件、 是 F # MVP,並具有作者及合著者著作。與他連絡ted@tedneward.com如果您想要讓他來自與您的小組,或是閱讀他的部落格blogs.tedneward.com

由於閱本篇文章的下列技術專家︰ Ward Bell