摘要:通過增加刪除元素改變布局的。譬如和控制元素顯示隱藏,或者改變元素行為的。譬如設計看過我之前介紹以手寫依賴注入的朋友應該已經對行為驅動多少有些了解了。她有,并且包含了至少一個和一個標簽。,將左邊的事件傳遞給了右邊的表達式通常就是事件處理函數。
前集回顧
在上一章里我們講了如何為angular2搭建開發環境(還沒搭起來的趕緊去看哦),并使之跑起來我們的第一個"My First Angular 2 App"。當然也有不少朋友反映環境搭建似乎比較復雜,整整一篇教程,最后只簡單輸出了一句話!這里我要說一句,學習新知識的確有一個陣痛的過程,尤其像angular2這種框架,引入了大量以前"前端"并不關心(沒有需求)的技術棧,這使得對于之前沒有接觸過這些概念的朋友的學習曲線陡然飆升,相信不少人看了上一章里開篇時的那些名詞后已經認識到這一點了!本教程主打實際操作,但也不會完全忽略理論,我們邊做邊理解。今天就接著上一章的余溫,我們來寫一個簡單component。
本章源碼:component
本章使用angular2版本為:2.4.5, webpack版本為: 2.2.0
先來看看我們將要完成的效果圖:
(注意動畫的部分)非常簡單的一個component,有木有?那好,我們現在要做的就是為這樣一個component描述需求:
她要能接受一個object用來描述初始值,如:isChecked(是否選中)、 txt(顯示文本)
當選中時,需要有橫線覆蓋文本;反之亦然
當用戶點擊復選框時,需要向上廣播該事件,由父組件(調用方)決定點擊時該做什么。這里我們需要在父組件里改變component的isChecked狀態,并使component重繪
她必須是一個處理Unidirectional Data Flow(單向數據流)的component,意思是傳入參數必須不可變(Immutable)
注:第4步里,我們使用Unidirectional Data Flow模型來更新數據,并沒有涉及到任何Reactive Programming的知識點
為了完成以上需求,我們需要了解下面知識點
什么是component或者這么問,AngularJS里有directive;angular2里有component,他們是什么關系?該如何理解angular2里的component?原諒我這里就不再詳述AngularJS里的directive了,直接介紹component:
Component: 簡單說,就是帶template的directive,也是最常見的組件形式。譬如:上一章中,ts/app.ts里的AppComponent。
Structural directive: 通過增加/刪除DOM元素改變DOM布局的directive。譬如:NgFor和NgIf
Attribute directive: 控制DOM元素顯示/隱藏,或者改變元素行為的directive。譬如:NgStyle
設計use case看過我之前介紹以BDD手寫依賴注入(dependency injection)的朋友應該已經對"行為驅動"多少有些了解了。當我們需要設計一個API或者組件時,最佳的方式就是先設計她的使用場景,從行為開始,對該API或者組件進行描述,最后再將缺失的“實現”部分補全就可以了。
假設我們將在上一章中的AppComponent里使用這個新的component,根據之前的需求描述,我們的使用場景應該是這個樣子的 :
import {Component, OnInit} from "@angular/core"; import {Item} from "./CheckableItem"; //該component使用checkable-item作為selector //并可以通過[item]屬性傳入一個object //還可以通過(onItemClicked)接受一個點擊事件 @Component({ selector: "my-app", template: `實現componentMy First Angular 2 App
` }) export class AppComponent implements OnInit { itemInfo: Item; //當實現OnInit接口時,必須重寫ngOnInit方法 //關于OnInit,詳見: //https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#hooks-overview ngOnInit() { //設定初始值 //根據需求第1條,包含兩個屬性 this.itemInfo = { isChecked: false, txt: "Hello World!" }; } //根據需求第3條,點擊component后,事件要 //冒泡到父組件(調用方) toggle(item: Item) { //當獲取到CheckableItem的點擊事件時, //給itemInfo重新賦值,并將isChecked置反 //注:重新賦值是根據需求第4條的不可變性 this.itemInfo = { isChecked: !item.isChecked, txt: item.txt }; } }
根據上述介紹,再結合之前的效果圖,我們要做的當然就是一個標準的Component。她有template,并且包含了至少一個input和一個label標簽。
有了使用場景(行為),接下來就是實現這個CheckableItem了:
touch ts/CheckableItem.ts
向剛創建的ts/CheckableItem.ts文件里寫入如下內容:
import {Component, Input, Output, EventEmitter, ChangeDetectionStrategy} from "@angular/core"; @Component({ //臟檢查策略,OnPush指當且僅當傳入參數的reference發生變更時 //觸發組件重繪。這和React中的shouldComponentUpdate異曲同工, //不過更先進(因為React還是需要手動實現的) //這也是上一步里itemInfo必須重新賦值的原因 changeDetection: ChangeDetectionStrategy.OnPush, selector: "checkable-item", //僅在當前component作用域下有效的class styles: [` .deleted{ text-decoration: line-through; } `], //template就如我們需求里的描述那樣,由一個input標簽和 //一個label標簽組成 template: `` }) export class CheckableItem { //item被聲明為Input,即會在父組件傳入參數時用到 @Input() item: Item; //onItemClicked被聲明為Output,用來在用戶點擊input標簽 //時向上冒泡事件 @Output() onItemClicked = new EventEmitter(); //監聽input上的click事件,當用戶點擊時,首先阻止默認行為 //因為是否變化(重繪)是由父組件決定的 //然后冒泡點擊事件 clickItem(e: MouseEvent) { e.preventDefault(); this.onItemClicked.emit(this.item); } } export interface ToggleItemHandler { (item: Item): void; } export interface Item { isChecked?: boolean; txt?: string; }
有朋友看到這里,對[]、 ()之類的綁定標簽表示不解,這里我們統一來解釋:
[target] = "expression",將右邊表達式對應的值綁定到左邊的target。譬如:在ts/app.ts里,我們使用[item]="itemInfo"將itemInfo對應的值綁定到了組件CheckableItem的item上,這樣,在CheckableItem里就可以通過this.item獲取到父組件傳進來的參數了。
(target) = "statement",將左邊的事件傳遞給了右邊的表達式(通常就是事件處理函數)。譬如:在ts/app.ts里,我們使用(onItemClicked)="toggle($event)"將CheckableItem冒泡上來的onItemClicked事件傳遞給了toggle函數。
[class.deleted]="item.isChecked",是class的一種特殊用法,指當item.isChecked表達式為真時,為該標簽的class里增加deleted;反之,則刪除該標簽class里的deleted
引入聲明打開之前寫的index.ts,增加CheckableItem引入:
import "core-js/es6"; import "core-js/es7/reflect"; import "zone.js/dist/zone"; import { NgModule } from "@angular/core"; import { BrowserModule } from "@angular/platform-browser"; import { AppComponent } from "./app"; import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; //引入CheckableItem import {CheckableItem} from "./CheckableItem"; @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent, CheckableItem ],//引入聲明 bootstrap: [ AppComponent ] }) class AppModule { } platformBrowserDynamic().bootstrapModule(AppModule);見證奇跡
OK,事已至此,我們是不是又該啟動一把程序看看效果了?
npm start
你又看到了偉大的效果:
下回預告:小刀升級 - 多component協作
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79203.html
摘要:前集回顧上一章里我們在里通過組合三個組件,并通過單向數據流的方式把她們驅動起來。設計每章都會提一下,先設計使用場景這種方式,我們稱之為,不了解的朋友參考以手寫依賴注入。 前集回顧 上一章里我們在AppComponent里通過組合InputItem、 CheckableItem、 Counter三個組件,并通過Unidirectional Data Flow(單向數據流)的方式把她們驅動...
摘要:我們使用了模式書寫,并引入了思想,這些以前只在里見到的設計,現在里也有體現,并且在本章中會著重講解多的協作。如果之前寫過,那對于這種書寫方式一定無比熟悉。每次數據的變更,無論是還是,都將變化冒泡到,然后由再向下逐級推送各組件是否重繪。 前集回顧 在上一章里我們講了如何在angular2下開發一個component(還沒做的趕緊去學吧)。我們使用了Unidirectional Data ...
angular2是什么?我猜不容我贅述,各位一定略有耳聞,無論是曾經AngularJS的擁躉,亦或是React的粉絲,都或多或少的對她有過一點了解。未見其物、先聞其聲,angular2在問世之前已經做足了宣傳,想必諸位也一定被下面各種詞匯所震懾,什么:TypeScript、 ES5、 ES6、 Dart、 Immutable、 Unidirectional Data Flow、 Reactive ...
摘要:為了簡單起見,在本文中將會使用。已經實例化了并且將它的模板載入到了元素中。中的依賴注入發生在該類的構造函數中,因此我們將在構造函數中注入。 國內 Angular2 資料比較少,這里看到一篇不錯的入門文章就分享過來了 —— Angular 2 快速上手,這里面還有很多有關于 Angular2 的文章,感興趣的朋友可以去看一看 目前angular2已經來到了beta版,這意味著它已經做好了...
摘要:的思想非常先進,摒棄了那種復雜的構建模式,采用了組件化開方的方,那我們一起來看一看,一個基礎的組件是什么樣子的呢。 angular2的思想非常先進,摒棄了angular1那種復雜的構建模式,采用了組件化開方的方,那我們一起來看一看,一個基礎的組件是什么樣子的呢。angular2-demoshowImg(http://static.xiaomo.info/images/angular.p...
閱讀 1084·2021-10-08 10:04
閱讀 3523·2021-08-05 10:01
閱讀 2278·2019-08-30 11:04
閱讀 1794·2019-08-29 15:29
閱讀 836·2019-08-29 15:12
閱讀 1670·2019-08-26 12:11
閱讀 3115·2019-08-26 11:33
閱讀 1163·2019-08-26 10:23