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约定的是传递的是不可变的对象

源于该组件或其子组件的事件

当在一个组件或者其子组件中触发了某一个事件时,这个组件的内部状态会更新。

显示的去执行变更检测

如果我们会发现如果我们设置一个定时器去修改,我们会发现页面不会有任何改变

ChangeDetectorRefdetectChanges() 告诉Angular在该组件和它的子组件中去执行变更检测。

ChangeDetectorRefmarkForCheck() 将视图明确标记已更改,再次对其进行检查

 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 可以防止投影的内容与你的服务混乱

posted @ 2020-03-31 18:24  猫神甜辣酱  阅读(771)  评论(0编辑  收藏  举报