我想执行一些基于窗口重新大小事件(在加载和动态)的任务。

目前我的DOM如下:

<div id="Harbour">
    <div id="Port" (window:resize)="onResize($event)" >
        <router-outlet></router-outlet>
    </div>
</div>

事件正确触发

export class AppComponent {
    onResize(event) {
        console.log(event);
    }
}

我如何从这个事件对象检索宽度和高度?

谢谢。


当前回答

这是我创建的一个简单而干净的解决方案,这样我就可以将它注入到多个组件中。

ResizeService.ts

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

@Injectable({
  providedIn: 'root'
})
export class ResizeService {

  constructor() {

    window.addEventListener('resize', (e) => {
      this.onResize.next();
    });

  }

  public onResize = new Subject();

}

在使用:

constructor(
  private resizeService: ResizeService
) { 

  this.subscriptions.push(this.resizeService.onResize.subscribe(() => {
    // Do stuff
  }));

}

private subscriptions: Subscription[] = [];

其他回答

这是我创建的一个简单而干净的解决方案,这样我就可以将它注入到多个组件中。

ResizeService.ts

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

@Injectable({
  providedIn: 'root'
})
export class ResizeService {

  constructor() {

    window.addEventListener('resize', (e) => {
      this.onResize.next();
    });

  }

  public onResize = new Subject();

}

在使用:

constructor(
  private resizeService: ResizeService
) { 

  this.subscriptions.push(this.resizeService.onResize.subscribe(() => {
    // Do stuff
  }));

}

private subscriptions: Subscription[] = [];

正确的方法是利用EventManager类来绑定事件。这让你的代码可以在其他平台上工作,例如使用Angular Universal进行服务器端渲染。

import { EventManager } from '@angular/platform-browser';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { Injectable } from '@angular/core';

@Injectable()
export class ResizeService {

  get onResize$(): Observable<Window> {
    return this.resizeSubject.asObservable();
  }

  private resizeSubject: Subject<Window>;

  constructor(private eventManager: EventManager) {
    this.resizeSubject = new Subject();
    this.eventManager.addGlobalEventListener('window', 'resize', this.onResize.bind(this));
  }

  private onResize(event: UIEvent) {
    this.resizeSubject.next(<Window>event.target);
  }
}

在组件中使用这个服务非常简单,只需将这个服务作为提供者添加到app.module中,然后在组件的构造函数中导入它。

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

@Component({
  selector: 'my-component',
  template: ``,
  styles: [``]
})
export class MyComponent implements OnInit {

  private resizeSubscription: Subscription;

  constructor(private resizeService: ResizeService) { }

  ngOnInit() {
    this.resizeSubscription = this.resizeService.onResize$
      .subscribe(size => console.log(size));
  }

  ngOnDestroy() {
    if (this.resizeSubscription) {
      this.resizeSubscription.unsubscribe();
    }
  }
}

在Angular2(2.1.0)中,我使用ngZone来捕获屏幕更改事件。

看一下这个例子:

import { Component, NgZone } from '@angular/core';//import ngZone library
...
//capture screen changed inside constructor
constructor(private ngZone: NgZone) {
    window.onresize = (e) =>
    {
        ngZone.run(() => {
            console.log(window.innerWidth);
            console.log(window.innerHeight);
        });
    };
}

希望这对你有所帮助!

我所做的就像Johannes Hoppe建议的那样:

import { EventManager } from '@angular/platform-browser'; import { Injectable, EventEmitter } from '@angular/core'; @Injectable() export class ResizeService { public onResize$ = new EventEmitter<{ width: number; height: number; }>(); constructor(eventManager: EventManager) { eventManager.addGlobalEventListener('window', 'resize', event => this.onResize$.emit({ width: event.target.innerWidth, height: event.target.innerHeight })); } getWindowSize(){ this.onResize$.emit({ width: window.innerWidth, height: window.innerHeight }); } }

在app.component.ts:

Import { ResizeService } from ".shared/services/resize.service" import { Component } from "@angular/core" @Component({ selector: "app-root", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent{ windowSize: {width: number, height: number}; constructor(private resizeService: ResizeService){ } ngOnInit(){ this.resizeService.onResize$.subscribe((value) => { this.windowSize = value; }); this.resizeService.getWindowSize(); } }

然后在你的app.component.html中:

<router-outlet *ngIf = "windowSize? "宽度> 1280 && windowSize?。高度> 700;errorComponent”> < / router-outlet > < ng-template # errorComponent > < app-error-component > < / app-error-component > < / ng-template >

这里有一个更好的方法。根据Birowsky的回答。

步骤1:用RxJS observable创建一个angular服务。

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

@Injectable()
export class WindowService {
    height$: Observable<number>;
    //create more Observables as and when needed for various properties
    hello: string = "Hello";
    constructor() {
        let windowSize$ = new BehaviorSubject(getWindowSize());

        this.height$ = (windowSize$.pluck('height') as Observable<number>).distinctUntilChanged();

        Observable.fromEvent(window, 'resize')
            .map(getWindowSize)
            .subscribe(windowSize$);
    }

}

function getWindowSize() {
    return {
        height: window.innerHeight
        //you can sense other parameters here
    };
};

步骤2:注入上述服务,并订阅在服务中创建的任何可观察对象,无论您希望在哪里接收窗口大小调整事件。

import { Component } from '@angular/core';
//import service
import { WindowService } from '../Services/window.service';

@Component({
    selector: 'pm-app',
    templateUrl: './componentTemplates/app.component.html',
    providers: [WindowService]
})
export class AppComponent { 

    constructor(private windowService: WindowService) {

        //subscribe to the window resize event
        windowService.height$.subscribe((value:any) => {
            //Do whatever you want with the value.
            //You can also subscribe to other observables of the service
        });
    }

}

充分理解响应式编程总是有助于克服困难的问题。希望这能帮助到一些人。