pengkobe / reading-notes

:stars: to record daily reading notes. I build an issue blog to record daily FE study notes. suggestion and comments are welcomed.
https://github.com/pengkobe/reading-notes/issues
MIT License
13 stars 1 forks source link

Angular 事件订阅 #448

Open pengkobe opened 6 years ago

pengkobe commented 6 years ago

参考自 stackoverflow 答案: How to listen for mousemove event on Document object in Angular

使用 @HostListener

这是事件订阅最佳实践, Angular 会自动订阅和取消事件

import {Component, NgModule, HostListener} from '@angular/core'

@Component({
  ...
})
export class MyComponent {
  @HostListener('document:mousemove', ['$event']) 
  onMouseMove(e) {
    console.log(e);
  }
  ..
}

在 dom 上订阅

在结合 ionic 使用时,遇到了内存泄漏,组件销毁,事件并没有被清除

@Component({
  selector: 'my-app',
  template: `
    <div (document:mousemove)="onMouseMove($event)" id="box"></div>
  `,
})
export class MyComponent {
  onMouseMove(e) {
    console.log(e);
  }
}

基于 Renderer Api

这算是比较底层的 Api 了,订阅事件后,还得手动取消订阅

import { Component, Renderer2 } from '@angular/core';

@Component({
  ...
})
export class MyComponent {
  globalListenFunc: Function;

  constructor(private renderer: Renderer2) {}

  ngOnInit() {
    this.globalListenFunc = this.renderer.listen('document', 'mousemove', e => {
      console.log(e);
    });
  }

  ngOnDestroy() {
    // remove listener
    this.globalListenFunc();
  }
}

使用 host 属性

最佳实践推荐大家不要使用,主要是代码维护问题, 事件名称变了需要改两次

@Component({
  ...
  host: {
    '(document:mousemove)': 'onMouseMove($event)'
  }
})
export class MyComponent {
  onMouseMove(e) {
    console.log(e);
  }
}

Observable.fromEvent

这应该是用起来最爽的方式了,但是也需要手动取消订阅,有一种情况列外,那就是使用 async 管道

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import { Subscription } from 'rxjs/Subscription';

@Component({
  ...
})
export class MyComponent {
  subscription: Subscription;

  ngOnInit() {
    this.subscription = 
         Observable.fromEvent(document, 'mousemove')
                           .subscribe(e => {
                             console.log(e);
                           });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

document.addEventListener

这个没啥好说的了,当然也是 Angular 极其抵制的方式,兼容性不说,维护也麻烦,此外也不利于 SSR