1.響應用戶時間 使用HostListener
裝飾器添加兩個事件處理器,它們會在鼠標進入或離開時進行響應。html
eg: @HostListener('mouseenter') onMouseEnter() {api
this.highlight('yellow');}數組
@HostListener('mouseleave')onMouseLeave(){promise
this.highlight(null);}app
privatehighlight(color:string){angular4
this.el.nativeElement.style.backgroundColor=color;}ide
二、使用數據綁定向指令傳遞值函數
@Input() highlightColor:string測試
注意看@Input裝飾器。它往類上添加了一些元數據,從而讓該指令的highlightColor能用於綁定。優化
它之因此稱爲輸入屬性,是由於數據流是從綁定表達式流向指令內部的。 若是沒有這個元數據,Angular就會拒絕綁定
@Input裝飾器把屬性設置成了公共屬性。
3
當Angular使用構造函數新建一個組件或指令後,就會按下面的順序在特定時刻調用這些生命週期鉤子方法:
鉤子 |
目的和時機 |
ngOnChanges() | 當Angular(從新)設置數據綁定輸入屬性時響應。 該方法接受當前和上一屬性值的 當被綁定的輸入屬性的值發生變化時調用,首次調用必定會發生在ngOnInit()以前。 |
ngOnInit() | 在Angular第一次顯示數據綁定和設置指令/組件的輸入屬性以後,初始化指令/組件。 在第一輪ngOnChanges()完成以後調用,只調用一次。 |
ngDoCheck() | 檢測,並在發生Angular沒法或不肯意本身檢測的變化時做出反應。 在每一個Angular變動檢測週期中調用,ngOnChanges()和ngOnInit()以後。 |
ngAfterContentInit() | 當把內容投影進組件以後調用。 第一次ngDoCheck()以後調用,只調用一次。 只適用於組件。 |
ngAfterContentChecked() | 每次完成被投影組件內容的變動檢測以後調用。 ngAfterContentInit()和每次ngDoCheck()以後調用 只適合組件。 |
ngAfterViewInit() | 初始化完組件視圖及其子視圖以後調用。 第一次ngAfterContentChecked()以後調用,只調用一次。 只適合組件。 |
ngAfterViewChecked() | 每次作完組件視圖和子視圖的變動檢測以後調用。 ngAfterViewInit()和每次ngAfterContentChecked()以後調用。 只適合組件。 |
ngOnDestroy | 當Angular每次銷燬指令/組件以前調用並清掃。 在這兒反訂閱可觀察對象和分離事件處理器,以防內存泄漏。 在Angular銷燬指令/組件以前調用。 |
4.寫服務的注意事項。
a.建立。hero.service.ts的文件,
b,將要引入的data(數據---靜態數據)建立一個單獨的ts。在hero.service.ts 裏用import引用
c,hero.service.ts裏視狀況使用promise
eg:
import {Injectable} from '@angular/core'
import {Hero} from '../class/hero'
import {HEROES} from '../staticdata/initdata'
@Injectable()
export class HeroService{
getHeroes(): Promise<Hero[]> {
return Promise.resolve(HEROES)
}
}
d.在調用的組件裏面實例化service類。注意不要這樣實例化。 heroService = new HeroService(); // don't do this,不妥;即作這兩份操做
1, constructor(private heroService: HeroService) { }
2, 在@Component組件的元數據底部添加providers數組屬性以下: providers: [HeroService]
五、建立最外端的app殼子時須要selector設置的字符串標籤在index.html 能找到。
eg:app 組件的代碼
@Component({
selector: 'app-root',
templateUrl: './appContainer.component.html'
})
index.html代碼
<body>
<app-root></app-root>
</body>
六、angular4的路由建立。
a、index.html頁面必須有<base href= "/">
b、在app.module.ts的imports屬性裏面加入RouterModule.forRoot(),裏面加入數組
eg:
imports: [
RouterModule.forRoot([
{
path: 'heroes',
component: HeroesComponent
}
])
],
c, 路由器就把激活的組件顯示在<router-outlet>裏面。而且經過a標籤進行導航跳轉<a routerLink="/heroes">Heroes</a>
d、路由的重定向
{
path:' ',
redirectTo:'/dashboard',
pathMatch:'full'
}
e、帶參數的路由配置,配置的結果是
配置: { path: 'detail/:id', component: HeroDetailComponent},
結果:/detail/11
注意:組件中數據的傳輸
一、從父組件的屬性綁定中接收英雄數據
二、新的HeroDetailComponent應該從ActivatedRoute
服務的可觀察對象params中取得id參數, 並經過HeroService服務獲取具備這個指定id的英雄數據。
f、路由若是是要進行迭代的話[routerLink]="['detail',hero.id]"
eg: <a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" class="col-1-4">
g.對於路由的配置能夠先將其填充到一個數組裏、再將定義的數組填充到router的方法裏
添加RouterModule.forRoot(routes)到imports。
若是有守衛服務,把它們添加到本模塊的providers中(本例子中沒有守衛服務)。
eg:
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'detail/:id', component: HeroDetailComponent },
{ path: 'heroes', component: HeroesComponent }
];
@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
七、編碼式路由跳轉<這三步在進行函數化路由跳轉時,在該跳轉組件上必須存在>
一、從angular路由器庫導入Router
import {Router} from '@angular/router'
二、在構造函數中注入Router
(與HeroService一塊兒)
constructor(
private router: Router,
private heroService: HeroService) { }
三、 實現gotoDetail(),調用路由器的navigate()方法
gotoDetail(): void { this.router.navigate(['/detail',this.selectedHero.id]);}
傳數值鍵參數
this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]);
八、路由中子組件獲取參數。
a: 1.在查詢參數中傳遞參數 /product?id=1&name=2 this.productId=this.routerInfo.snapahot.queryParams["id"]
步驟分解。| 注入ActivatedRoute .eg: import {ActivatedRoute, Router} from "@angular/router"
||在構造函數中構造。eg: constructor(private routerIonfo:ActivatedRoute) { }
||||在本組件建立一個變量 eg: private productId:number
|V在本組件中加方法。 eg: ngOnInit(){
this.productId=this.routerInfo.snapshot.queryParams["id"]
}
注意:這種方法只能初始化第一次的時候獲取一次數據不能,隨數據變化而變化。如須要變化能夠採用訂閱發佈者模式。
b.在路由路徑中傳遞數據
//路由配置{path:'/product/:id'}
//路由顯示方式Restful=>/product/1
/** 獲取參數 *
/=>ActivatedRoute.params[id]
export class HomeComponent implements OnInit {
private homeId:number;
constructor(private routerIonfo:ActivatedRoute) { }
ngOnInit() {
this.homeId=this.routerIonfo.snapshot.params["id"];
}
}
優化版就是加訂閱
this.routerIonfo.params.subscribe((params:Params)=>this.homeId=params["id"]);
注意: a、只有當你肯定你的頁面不會從自身路由到自身,或者只有一隻方式路由到此頁面的話就可使用參數快照方式,不肯定的話最好使用參數訂閱的方式。
b、防止頁面跳轉沒定義的路由致使程序奔潰須要配置通配符路由:
eg: { path: '**', component: PageNotFoundComponent }
c、 { path: '', redirectTo: '/heroes', pathMatch: 'full' } 在本應用中,路由器應該只有在完整的URL等於''時才選擇HeroListComponent組件,所以咱們要把pathMatch設置爲'full'。
d、 pathMatch的另外一個可能的值是'prefix',它會告訴路由器:當剩下的URL以這個跳轉路由中的prefix值開頭時,就會匹配上這個跳轉路由。
八、路由模塊
路由模塊有一系列特性:
imports: [
HeroesModule,
AppRoutingModule],
AppRoutingModule
是最後一個。最重要的是,它位於HeroesModule以後。路由配置的順序很重要。 路由器會接受第一個匹配上導航所要求的路徑的那個路由。
當全部路由都在同一個AppRoutingModule時,咱們要把默認路由和通配符路由放在最後(這裏是在/heroes路由後面), 這樣路由器纔有機會匹配到/heroes路由,不然它就會先遇到並匹配上該通配符路由,並導航到「頁面未找到」路由。
一些注意
問題1.
解決方法:
引入下面代碼:
import 'rxjs/add/operator/switchMap';
2、
<li *ngFor="let heroa of heroes" (click)="onSelect(heroa)">
<span>{{heroa.id}}</span><h1>{{heroa.name}}</h1>
<button class="delete"(click)="delete(hero);$event.stopPropagation()">X</button>
</li>
注:$event.stopPropagation()阻止事件冒泡,阻止它向上觸發li的事件