angular2:如何使用observables去抖窗口:调整大小

Lit*_*tud 17 observable angular

所以我试图找出一种方法去除窗口:使用observable调整事件大小,所以只有在用户停止调整大小窗口或者一段时间没有大小改变(例如1秒)之后才会调用某种函数.

https://plnkr.co/edit/cGA97v08rpc7lAgitCOd

import {Component} from '@angular/core'

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div (window:resize)="doSmth($event)">
      <h2>Resize window to get number: {{size}}</h2>

    </div>
  `,
  directives: []
})
export class App {
  size: number;
  constructor() {
  }

  doSmth(e: Event) {
    this.size = e.target.innerWidth;
  }
}
Run Code Online (Sandbox Code Playgroud)

只是一个使用窗口的简单示例:调整大小并显示它立即作出反应(使用"在单独窗口中启动预览").

Thi*_*ier 34

我认为你不能使用observable以这种方式去抖动.事实上,这些东西现在不支持开箱即用,但有一个未解决的问题:

为了实现您的目标,您可以直接使用它Observable.fromEvent来获取此事件的可观察性.因此,您可以debounceTime在此可观察对象上应用运算符.

这是一个示例:

@Component({
  (...)
})
export class App {
  size: number;
  constructor() {
    Observable.fromEvent(window, 'resize')
        .debounceTime(1500)
        .subscribe((event) => {
          this.doSmth(event);
        });
  }

  doSmth(e: Event) {
    console.log('do smth');
    this.size = e.target.innerWidth;
  }
}
Run Code Online (Sandbox Code Playgroud)

看到这个plunkr:https://plnkr.co/edit/uVrRXtnZj8warQ3qUTdN p = preview


小智 11

在我们的一个应用程序中,我们也有Thierry Templier提出的实现,但是我注意到Angular的更改检测在窗口调整大小时触发了很多,这使得我们的应用程序在调整大小时变慢.

通过使用区域和主题来修复它,如下所示:

private changeSubject = new Subject<number>();

constructor(private zone: NgZone) {
  this.zone.runOutsideAngular(() => {
    Observable.fromEvent(window, 'resize')
    .debounceTime(1500).distinctUntilChanged().subscribe((e: Event) => {
      this.zone.run(() => {
        this.changeSubject.next(e);
      })
    }
    )
  });
  this.changeSubject.subscribe((e: Event) => { this.doSmth(e); });
}
Run Code Online (Sandbox Code Playgroud)

请在此处查看plunker问题(调整大小屏幕和监视控制台).

并与修复此问题plunker 这里(调整屏幕和手表控制台).


Lon*_*ren 5

您可以使用@HostListener装饰器。这是订阅此类事件的常用方法。

@Component({
   // ...
})
export class App {
  private changeSize = new Subject();

  constructor() {
    this.changeSize
    .asObservable()
    .pipe(
      throttleTime(1000)
    )
    .subscribe(innerWidth => console.log('innerWidth:', innerWidth));
  }

  @HostListener('window:resize', ['$event.target'])
  public onResize(target) {
    this.changeSize.next(target.innerWidth);
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以@HostListener 在此处此处阅读更多信息。