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