動態獲取路由的id
// path: 'pro/:id',
import {ActivatedRoute} from '@angular/router'
export class EnabledComponent implements OnInit {
constructor(private route:ActivatedRoute) {
}
ngOnInit(): void {
this.route.paramMap.subscribe(params=>{
console.log(params.get('id'));
})
}
}
<button type="button" [routerLink]="['/list', id]">Show List</button>
路由導航
this.router.navigate(['/list', this.id]);
監控路由發生改變的事件
import {Router, NavigationEnd} from '@angular/router';
constructor(private route: Router) {}
this.route.events.subscribe((event: NavigationEnd) => {
if (event instanceof NavigationEnd) {
// 事件
}
});
angular 學習教程
https://alligator.io/angular/
async 管道
當angular 銷毀該組件時,async管道將自動停止,達到一定的優化效果
<div *ngFor="let item of list|async">{{item}}</div> <h1>{{time|async|date:'yyyy-MM-dd hh:mm:ss'}}</h1> ts export class BlockComponent implements OnInit { public time = new Observable<string>((observable: Observer<string>) => { setInterval(() => observable.next(new Date().toString()), 1000) }); public list: Promise<any>; ngOnInit(): void { this.list = new Promise(res => res([1, 2, 3])); } }
@NgModule理解exports的使用
exports就是一個導出模塊,這樣的話可以理解成這可能是一個公共模塊,例如剛開始使用ng-zorro的使用,就糾結難道我每一個模塊都要這樣導入嗎?看到這個屬性后終於理解了
創建一個公共模塊 ng g m my-commom import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {NgZorroAntdModule, NZ_I18N, zh_CN} from 'ng-zorro-antd'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {registerLocaleData} from '@angular/common'; import zh from '@angular/common/locales/zh'; import {RouterModule} from "@angular/router"; registerLocaleData(zh); const commom = [ CommonModule, FormsModule, ReactiveFormsModule, NgZorroAntdModule, RouterModule,]; @NgModule({ declarations: [], imports: [ ...commom ], exports: [...commom], providers: [{provide: NZ_I18N, useValue: zh_CN}] }) export class ComomModule { } 然后在其他模塊的導入這個公共模塊就可以啦 import :[CommomModule]
變更策略檢測
默認情況下,Angular使用
ChangeDetectionStrategy.Default
策略來進行變更檢測也就是每當用戶事件,計時器,XHR,promise 等事件使數據將發生改變時,所有的組件中都會執行變更檢測
例如當你有個定時器的時候
<h1>{{time|async|date:'yyyy-MM-dd hh:mm:ss'}}</h1> <div>{{runChange}}</div> ts public time = new Observable<string>((observable: Observer<string>) => { setInterval(() => observable.next(new Date().toString()), 1000) }); get runChange(){ console.log('變了'); return true }
每當我們點擊按鈕時,或者定時器在頁面的變化時,Angular將會執行一遍變更檢測循環,在頁面中我們會看到兩行'變了'的日志
這種技術稱作臟檢查,為了知道視圖是否需要更新,Angular需要訪問新值並和舊值比較來判斷是否需要更新視圖
OnPush變更檢測策略
我們把組件的ChangeDetectionStrategy
設置成ChangeDetectionStrategy.OnPush
https://angular.io/api/core/ChangeDetectionStrategy
@Component({ selector: 'app-block', templateUrl: './block.component.html', styleUrls: ['./block.component.less'], changeDetection:ChangeDetectionStrategy.OnPush //添加 })
Input引用發生改變
我們與angular約定的是傳遞的是不可變的對象
源於該組件或其子組件的事件
當在一個組件或者其子組件中觸發了某一個事件時,這個組件的內部狀態會更新。
顯示的去執行變更檢測
如果我們會發現如果我們設置一個定時器去修改,我們會發現頁面不會有任何改變
ChangeDetectorRef
的detectChanges()
告訴Angular在該組件和它的子組件中去執行變更檢測。
ChangeDetectorRef
的markForCheck()
將視圖明確標記已更改,再次對其進行檢查import {ChangeDetectorRef} from '@angular/core'; constructor(private Changes: ChangeDetectorRef) { } let a = null; clearTimeout(a); setTimeout(() => { this.aaa = 100; this.Changes.detectChanges() // this.Changes.markForCheck() 這個也可以進行強制更新 }, 2000)
在理解了onPush
的強大之后,我們可以理解onPush
組件越多,Angular需要執行的檢查就越少
限制檢測發生變化的頻率
每5s執行一次明確本地的檢查 constructor(private ref: ChangeDetectorRef) { ref.detach(); //關閉檢測 setInterval(() => { this.ref.detectChanges(); //開啟檢測 }, 5000); }
通過一個狀態來判斷子組件是否被檢測
5s后取消子組件檢測
父組件
<live-data [live]="live"></live-data>
`ts`
live=true
ngOnInit(): void {
setTimeout(() => {
this.live = false
}, 5000)
}
子組件
@Input()
set live(value: boolean) {
if (value) {
this.ref.reattach();// 重新附加檢測
} else {
this.ref.detach(); //關閉檢測
}
}
@Component({
selector: 'live-data',
inputs: ['live'], //記得加上這個,暫時還沒理解這個是什么意思,后面再解釋
}
viewProviders和providers的區別
在使用了viewProviders
就別使用<ng-content></ng-content>
,不然會報錯
如果使用<ng-content></ng-content>
則應該用providers
viewProviders
將提供者限制為非計划內容的子對象,但是providers
允許子對象使用提供者
使用viewProviders
可以防止投影的內容與你的服務混亂