angular9的学习(二)
动态获取路由的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
可以防止投影的内容与你的服务混乱
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬