Angular 之监听变量变化 | 更文挑战第14天

1,615 阅读1分钟

这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

1. TS 中如何监听变量的变化

使用 KeyValueChanges 方法

html

<button (click)="changeName()">改变变量的值</button>

ts

import { KeyValueChanges, KeyValueDiffer, KeyValueDiffers } from '@angular/core';

export class Customer {
  firstName: string;
  favoriteColor: string;
}

export  class xx {
   private customerDiffer: KeyValueDiffer<string, any>; // 注入 KeyValueDiffer
   private customer: Customer;

    constructor(
        private differs: KeyValueDiffers
    ) {
        this.customer = new Customer();
        this.customerDiffer = this.differs.find(this.customer).create();  // 创建监听
    }
  
  customerChanged(changes: KeyValueChanges<string, any>) {
    console.log('changes', changes);
    /* 如果你想看到详情可以这样:
      changes.forEachRemovedItem((record) => ...);
      changes.forEachAddedItem((record) => ...);
      changes.forEachChangedItem((record) => ...);
    */
  }

  ngDoCheck(): void {
      const changes = this.customerDiffer.diff(this.customer); // 比较监听,输出是否有变化
      if (changes) {
        this.customerChanged(changes);
      }
  }

  changeName(){
    this.customer.firstName+= "张三";
  }

}

2. 模板表单中监听表单控件值的变化

使用ngModelChange 双向绑定监听

<input type="text" (ngModelChange)="doSomething($event)" [ngModel]="customer.firstName">

ts

doSomething(event) {
  console.log(event); // logs model value
}

3. 动态表单中监听表单控件值的变化

使用valueChanges监听,它会把表单变化的项输出出来

 ngOnInit() {
    this.form = this.fb.group({
     // xxx
    });
  }
  
  ngAfterViewInit(): void {
    this.form.valueChanges.subscribe((change) => {
      console.log(change)
     })
  }

4. 彩蛋

拖动和点击同时触发,如何判断是点击还是拖拽?

问题
拖拽的时候会触发点击事件,所以得分清是拖拽还是点击

原理介绍

  • 点击一般使用click,但是我们这里需要用mouseDownmouseUp来实现
  • 拖动过程中会触发三个事件
    • mouseDownmouseMovemouseUp

解决办法
所以我们在mouseDown事件中记录鼠标的位置,在mouseUp 时比较此时的位置是否相同则可判断是点击还是拖拽。 mouseup html 中绑定 mousedownmouseup事件

<div
  cdkDrag
  (mousedown)="onMousedown($event)"
  (mouseup)="onMouseup($event)"
>
</div>

ts

  dowmPosi = []; // 按下时的鼠标位置
  upPosi = [] // 松开时的鼠标位置

  // 鼠标按下事件
  onMousedown(event: MouseEvent){
    const { pageX, pageY } = event;
    this.dowmPosi.push(pageX, pageY);
  }
  
  // 鼠标松开事件
  onMouseup(event: MouseEvent){
    const { pageX, pageY } = event;
    this.upPosi.push(pageX, pageY)
    if(_.isEqual(this.dowmPosi, this.upPosi)){ // 比较鼠标按下和松开数据是否一致, isEqual 是 lodash 立比较两个变量值是否相等的方法
      // 这里去执行点击事件做的事情
    }
    this.resetMouseFlag();
  }

  // 重置变量数据
  resetMouseFlag(){
    this.dowmPosi = [];
    this.upPosi = [];
  }

更多用法更新于 github