Angular2——小結(jié)

入坑

前端開(kāi)發(fā)者估計(jì)跟我的心思是一樣的虚倒,剛對(duì)AngularJS寫(xiě)出了點(diǎn)頭緒美侦,懂了點(diǎn)皮毛,轉(zhuǎn)眼升級(jí)版Angular4.x就出現(xiàn)了魂奥,心中是各種禮貌的問(wèn)候的菠剩。。耻煤。

表情包1

默默擦眼淚具壮。。哈蝇。我們來(lái)看下要從哪幾個(gè)方面入手棺妓。以下目錄~

  • 路由
  • 指令
  • 組件
  • 模塊
  • 服務(wù)

Angular拋棄了原本的 ng-controller指令、復(fù)雜的$scope炮赦,保留了路由嵌套怜跑、依賴(lài)注入機(jī)制。還有一些指令的寫(xiě)法吠勘,例如ng-click 改成(click) 性芬、ng-repeat改成 *ngFor等等,后續(xù)指令篇會(huì)詳細(xì)提出看幼。Angular的最大改造是用Typescript為默認(rèn)開(kāi)發(fā)語(yǔ)言批旺,組件化的思維。

入坑前需要了解一下Angular-Cli工具诵姜。在項(xiàng)目初始化的時(shí)候,可以開(kāi)箱即用,搭配一系列完整的工具

npm install @angular/cli -g
ng new study-ng
cd study-ng
ng serve

打開(kāi)package.json文件

    "@angular/animations": "^5.2.0",
    "@angular/common": "^5.2.0",
    "@angular/compiler": "^5.2.0",
    "@angular/core": "^5.2.0",
    "@angular/forms": "^5.2.0",
    "@angular/http": "^5.2.0",
    "@angular/platform-browser": "^5.2.0",
    "@angular/platform-browser-dynamic": "^5.2.0",
    "@angular/router": "^5.2.0",

  • @angular/common:
    • CommonModule:通用模塊棚唆,包含內(nèi)置指令ngIf暇赤,ngFor
  • @angular/core:包含多種常用的模塊
    • NgModule(模塊定義裝飾器)
    • Component(組件定義裝飾器)
    • Directive (指令定義裝飾器)
    • ElemtRef (元素引用)
    • ViewChild (獲取子元素)
    • Output Input EventEmitter Render 等等等。宵凌。鞋囊。。
  • @angular/forms:
    • Validators:表單校驗(yàn)
  • @angular/http:
    • HttpModule:http請(qǐng)求模塊
  • @angular/router:
    • RouterModule:路由模塊

天啊嚕O贡埂!太多了挺益。~~ps:這些都是擼過(guò)代碼后從頭看理論概念的時(shí)候能理解透的望众。伞辛。蚤氏。硬生生的啃文字竿滨,小火雞我是受不了的。殿怜。头谜。

表情包2

生命周期

組件周期鉤子函數(shù) 說(shuō)明
constructor(myService:MyService) 類(lèi)的構(gòu)造器會(huì)再其他生命周期函數(shù)前調(diào)用柱告,在該方法中完成服務(wù)的依賴(lài)注入
ngOnChanges 當(dāng)被綁定的輸入屬性的值發(fā)生變化時(shí)調(diào)用际度,首次調(diào)用一定會(huì)發(fā)生在 ngOnInit之前乖菱。(@input屬性(輸入屬性)發(fā)生變化時(shí)窒所,會(huì)調(diào)用吵取。非此屬性皮官,不會(huì)調(diào)用捺氢。)
ngOnInit 只執(zhí)行一次,dom操作可放在其中
ngDoCheck 更新檢測(cè)機(jī)制郁岩,如果組件內(nèi)發(fā)生異步事件问慎,就會(huì)檢查整個(gè)組件樹(shù)
ngAfterContentInit 組件內(nèi)容初始化之后調(diào)用
ngAfterContentChecked
ngAfterViewInit 組件視圖初始化后調(diào)用
ngAfterViewChecked
ngOnDestroy 實(shí)例被銷(xiāo)毀前調(diào)用如叼,僅調(diào)用一次

進(jìn)入正文啦 ~


image.png

一、路由篇

1歇终、route設(shè)置三步走

(1)评凝、手動(dòng)添加路由文件

image

appRoutes的配置

import { Routes } from "@angular/router";
//引入組件等奕短。翎碑。。遣铝。
import { ChildComponent } from'./home/child/child.component'

//定義并輸出常量路由
export const appRoutes:Routes=[
  //地址欄輸入 .../example翰蠢,加載組件ExampleComponentComponent
  { path:'example',component:ExampleComponentComponent},
  { path:'home',
    component:HomeComponent,
    children:[{//子路由   .../home/home-child,加載ChildComponent組件
      path:'child',
      component:ChildComponent,
      //children:...
    }]
  },
  { path:'home/brother',component:BrotherComponent},//下圖示例
  {
    //如果 地址欄沒(méi)輸入定義的路由就跳轉(zhuǎn)到home路由界面
    path:'',
    redirectTo:'home',
    pathMatch:'full'
  }
]

子路由的區(qū)別

child組件是通過(guò)一級(jí)路由被載入到homeComponent的html模板的<router-outlet>下方

  <div routerLink="/example">栗子</div>

  <div routerLink="./brother">brother</div>

  <div routerLink="child">child的內(nèi)容會(huì)展示在當(dāng)頁(yè)面  router-outlet  中</div>
  <!-- <div [routerLink]="['./child']">child的內(nèi)容會(huì)展示在當(dāng)頁(yè)面---另一種寫(xiě)法</div> -->
  <router-outlet></router-outlet>

<router-outlet>路由占位符,可以理解為渲染路由組件的區(qū)域蝇裤,一個(gè)組件只有一個(gè)無(wú)名的<router-outlet>可以有多個(gè)有名的<router-outlet>栓辜,例如:<router-outlet name=”a”>藕甩、<router-outlet name=”b”>

(2)狭莱、app.module.ts文件中引用

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'
import { appRoutes } from './route.module'
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    //注入模塊中腋妙,forChild只能用于子路由,forRoot只能用于根模塊
    // forRoot有一個(gè)可選的配置參數(shù)匙睹,里面有四個(gè)選項(xiàng)
    // enableTracing :在console.log中打印出路由內(nèi)部事件信息
    // useHash :把url改成hash風(fēng)格 /#/
    // initialNavigation : 禁用初始導(dǎo)航痕檬,沒(méi)用過(guò)梦谜。改淑。
    // errorHandler :使用自定義的錯(cuò)誤處理朵夏,來(lái)拋出報(bào)錯(cuò)信息榆纽;
    RouterModule.forRoot(appRoutes,{useHash: true}),   //添加 !饥侵!
    BrowserModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

(3)躏升、在index.html中添加

<body>
  <app-root></app-root>
</body>

2膨疏、其他注意點(diǎn)

(1)佃却、路由跳轉(zhuǎn)中可加上參數(shù)

import { Component, OnInit } from '@angular/core';
import {  Router } from '@angular/router';

@Component({
 //忽略...
})
export class HomeComponent implements OnInit {

  constructor(
    public router:Router
  ) { }

  goTopage(page,queryParams){
    this.router.navigate([page],{ queryParams: queryParam })
  }
}

ps:可通過(guò)navigate()方法來(lái)實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)

(2)饲帅、forChild的使用

根模塊中使用forRoot(),子模塊中使用forChild()

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
export const routes: Routes = [];

@NgModule({
  imports: [
    RouterModule.forChild(routes)
  ],
  // ...
})
export class ChildModule {  }

二灶泵、指令篇

  • 結(jié)構(gòu)指令

1丘逸、 NgClass:接收一個(gè)對(duì)象深纲,key為class名,value為值儒喊,表示是否用改樣式

<p [ngClass]="{'fadeIn'}">example</p>
<p [ngClass]="{'fadeIn':!hidden}">example</p>

2怀愧、NgStyle:設(shè)置dom元素的css屬性芯义,可以動(dòng)態(tài)的

<div [ngStyle]="{'color':'#999'}">寫(xiě)樣式的東西咯</div>
<div [ngStyle]="{'color':gray?'#999':'#000'}">寫(xiě)樣式的東西咯</div>

3扛拨、NgFor:創(chuàng)建dom元素举塔,類(lèi)似ng1中的ng-repeat

    const list = [ {name:'a'} ,{name:'b'}]
    const array = [1,2,3,4]
<ul>
    <li *ngFor="let item of list"></li>
</ul>
<ul>
    <li *ngFor="let item of array,let i = index">第個(gè)</li>
</ul>

4、NgIf:設(shè)置dom元素的展示或隱藏

<div *ngIf="show">要不要展示咧渴频?<div>
  • 自定義屬性指令

當(dāng)內(nèi)置指令還不能滿(mǎn)足實(shí)際業(yè)務(wù)場(chǎng)景時(shí)北启,Angular中提供了自定義指令來(lái)滿(mǎn)足特定的場(chǎng)景需求

舉個(gè)栗子:給用自定義屬性的內(nèi)容加點(diǎn)特殊處理

1暖庄、第一步培廓,創(chuàng)建一個(gè)directive文件

ng generate directive child-directive

此時(shí)app.module中已增加ChildDirectiveDirective指令

2肩钠、第二步价匠,在模塊中引入我們定義的指令

//...
@NgModule({
  imports: [ BrowserModule ],
  declarations: [
    AppComponent,
    ChildDirectiveDirective//!!申明我們定義的指令
  ],
  bootstrap: [ AppComponent ]
})
//...

3踩窖、第三步晨横,擼出directive的邏輯

import { Directive,ElementRef,Renderer2,Input } from '@angular/core';

@Directive({//@Directive裝飾器指定了一個(gè)選擇器名稱(chēng)手形,用于指出與此指令相關(guān)聯(lián)的屬性的名字
  selector: 'color,[color]'
})
export class ChildDirectiveDirective {
  @Input('color')color : any;//@Input 為組件提供數(shù)據(jù)
  private elem;
  constructor(private renderer:Renderer2,elementRef:ElementRef) { 
    this.elem = elementRef//elementRef可直接獲取到dom
  }
  ngOnInit(){
    this.renderer.setStyle(this.elem.nativeElement,'color',this.color)//讓頁(yè)面上該dom渲染該樣式
  }
}

4库糠、第四步瞬欧,在html中引用該自定義屬性

組件中添加該指令,可自定義展示的樣式

<div [color]='"red"'>測(cè)試下咯</div>

三艘虎、組件

是時(shí)候祭出我的超簡(jiǎn)單基礎(chǔ)組件第一套G晏2持汀妄呕!switch組件的實(shí)現(xiàn)

look look 組件實(shí)現(xiàn)的部分

  • 1绪励、 第一步疏魏,實(shí)現(xiàn)switch的樣式

首先把switch輪子的樣式寫(xiě)好


  • switch.component.html
    <span>
    <label class="iSwitch">
      <input type="checkbox" (click)="switch($event)" #switchInput >
      <i></i>
    </label> 
    </span>
    
    

具體css樣式怎么擼的我就不貼了,自行擼官份!下面主要講組件的實(shí)現(xiàn)

  • 2舅巷、 第二步,實(shí)現(xiàn)switch輪子的邏輯
  • switch.component.ts
import { Component, OnInit, Output, EventEmitter, Input, ViewChild,ElementRef,Renderer2 } from '@angular/core';

@Component({
    selector:'switch',//selector就是使用該組件時(shí)候的標(biāo)簽名字
    templateUrl:'./switch.component.html',
    styleUrls:['./switch.component.scss']
})

export class SwitchComponent implements OnInit {
  public open:boolean;
  @ViewChild('switchInput' , {read: ElementRef}) switchInput: ElementRef;
  //ElementRef 直接獲取了輪子中<input>dom元素
  @Output() onchange: EventEmitter<any> = new EventEmitter<any>();
  //前面提到@input,可以從demo子組件中獲取數(shù)據(jù)搁凸,@output則相當(dāng)于方法的綁定情屹,將onchange方法綁定到demo中垃你,在父作用域中處理事件。output一般都是一個(gè)EventEmitter實(shí)例皆刺,通過(guò)emit()方法將父組件取到的值返回給demo子組件中
  constructor(private renderer: Renderer2 ,) { }
  ngOnInit() {
  }
  switch(e){
    this.open = !this.open
    this.onchange.emit(this.switchInput.nativeElement.checked)//返回給子組件demo中
  }
}

  • 3羡蛾、 第三步锨亏,使用輪子的方式

使用輪子的代碼,使用的方法:

demo.component.html

<switch (onchange)="getSwitchVaule($event)"></switch>

demo.component.ts

 export class SwitchDemo { 
  public getSwitchVaule(v){
    //頁(yè)面中的onchange方法是父組件提供的 
    console.log(‘結(jié)果:’,v) 
  }
}

暫停一下捐迫,來(lái)一些啰嗦J┐鳌赞哗!

看到這是否還會(huì)一臉懵逼肪笋?乾颁??我們來(lái)解讀下實(shí)現(xiàn)的過(guò)程湿右。

使用<switch>標(biāo)簽名毅人,可以實(shí)例化一個(gè)switch組件丈莺。</p>

獲取到父組件通過(guò)@Output提供的onchange方法弛秋,在這個(gè)方法中蟹略,<switch>父組件處理switch開(kāi)關(guān)的值遏佣,處理后的值状婶。通過(guò)emit()方法返還給demo組件中的 public getSwitchVaule(v)方法中

  • 4、第四步钓猬,給輪子增加點(diǎn)初始值

接著我們就會(huì)思考switch組件是否可以添加一些默認(rèn)值碴倾,進(jìn)入頁(yè)面默認(rèn)就是打開(kāi)的狀態(tài)逗噩。

也就是demo組件如何給父組件通信,告訴父組件我現(xiàn)在是打開(kāi)的狀態(tài)跌榔,這里可以借助添加屬性的方法來(lái)實(shí)現(xiàn)

<switch (onchange)="getSwitchVaule($event)" [default]=true>

[defalut]是一個(gè)自定義的屬性异雁,并且傳值true,可在父組件輪子中去獲取demo的傳值

//...
export class SwitchComponent implements OnInit {
  @Input('default') defaultData: any;//默認(rèn)關(guān)閉狀態(tài)
  constructor(...) { }
  ngOnInit(){
    this.initDefault();//設(shè)置一個(gè)獲取初始默認(rèn)值的函數(shù)
  }
  initDefault(){
    //this.defaultData 可獲取到demo組件中傳值過(guò)來(lái)的true
    if(this.defaultData){
      this.switchInput.nativeElement.checked = true;//設(shè)置頁(yè)面switch的開(kāi)關(guān)狀態(tài)
      this.open = !this.open
    }
  }
} 
//...

  • 5僧须、最后一點(diǎn)纲刀,自行思考!5F健示绊!

現(xiàn)在switch組件已經(jīng)可以支持點(diǎn)擊打開(kāi)或者關(guān)閉開(kāi)關(guān),并且可接收一個(gè)默認(rèn)開(kāi)關(guān)值暂论。至于switch的禁用狀態(tài)disabled也同理可實(shí)現(xiàn),這個(gè)大家就自行思考啦~道理都是一樣的啦 ~~~

四匪傍、模板

五薪棒、服務(wù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末泼各,一起剝皮案震驚了整個(gè)濱河市及塘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)雨涛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)后众,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人括堤,你說(shuō)我怎么就攤上這事。” “怎么了纠炮?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)怖辆,這世上最難降的妖魔是什么特咆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任菜职,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嘶居。我一直安慰自己佑吝,他們只是感情好戈钢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布恩溅。 她就那樣靜靜地躺著,像睡著了一般弦悉。 火紅的嫁衣襯著肌膚如雪劈猪。 梳的紋絲不亂的頭發(fā)上浇冰,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死爽锥,一個(gè)胖子當(dāng)著我的面吹牛雇毫,可吹牛的內(nèi)容都是我干的馅闽。 我是一名探鬼主播峦甩,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼球凰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了英遭?” 一聲冷哼從身側(cè)響起多律,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤收毫,失蹤者是張志新(化名)和其女友劉穎昔搂,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蝙砌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片军拟。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遣耍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出炮车,到底是詐尸還是另有隱情舵变,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布瘦穆,位于F島的核電站纪隙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏扛或。R本人自食惡果不足惜绵咱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望告喊。 院中可真熱鬧麸拄,春花似錦、人聲如沸黔姜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)秆吵。三九已至淮椰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纳寂,已是汗流浹背主穗。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毙芜,地道東北人忽媒。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像腋粥,于是被迫代替她去往敵國(guó)和親晦雨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容