如何从有角服务中订阅window.resize?

时间:2019-11-27 06:42:40

标签: angular angular-services

我尝试过,

WindowService

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

interface WindowSize {
  width?: number;
  height?: number;
}

@Injectable({
  providedIn: 'root'
})
export class WindowService {
  webWindow = window;
  windowHeight: number;
  windowWidth: number;
  windowSize: number;
  constructor() {

    this.getWindowSize = this.getWindowSize.bind(this);

  }


  getWindowSize(): Observable<any> {
    return this.webWindow.addEventListener('resize', ()=> {
      this.windowSize = {
        width: window.innerWidth,
        height: window.innerHeight
      };
      return this.windowSize;
    });
  }
}

我要订阅getWindowSize方法的组件

  ngOnInit() {
    this.loadUser();
    this.windowSize = this.windowService.getWindowSize().subscribe(data=> {
      console.log(data)
      this.windowSize = data;
    }); 
  }

我得到的错误是

  

AppComponent.ngfactory.js? [sm]:1错误,TypeError:无法读取   未定义的属性“订阅”       在FeedlistComponent.ngOnInit

2 个答案:

答案 0 :(得分:1)

这是一项不会在服务器端环境中引发任何错误并且不会泄漏订阅的服务:

import {DOCUMENT} from '@angular/common';
import {Inject, Injectable} from '@angular/core';
import {fromEvent, NEVER, Observable} from 'rxjs';

// @dynamic
@Injectable({
    providedIn: 'root',
})
export class ResizeService extends Observable<Event> {
    private readonly resize$: Observable<Event>;

    constructor(
        @Inject(DOCUMENT) {defaultView}: Document,
    ) {
        super(subscriber => this.resize$.subscribe(subscriber));

        this.resize$ = defaultView ? fromEvent(defaultView, 'resize') : NEVER;
    }
}

注意:注释// @dynamic很重要,否则AOT构建会因构造函数参数中的Document类型而失败。

注意:您也可以考虑限制这些事件。

用法:

export class MyComponent {
    constructor(@Inject(ResizeService) resize$: Observable<Event>) {
        resize$.subscribe(console.log);
    }
}

答案 1 :(得分:0)

addEventListener不返回可观察值。您可以使用fromEvent(window, 'resize')HerefromEvent的文档。