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

目前我的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);
    }
}

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

谢谢。


当前回答

@Günter的答案是正确的。我只是想提出另一种方法。

你也可以在@Component()装饰器中添加主机绑定。你可以像这样把事件和所需的函数调用放在host-metadata-property中:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  host: {
    '(window:resize)': 'onResize($event)'
  }
})
export class AppComponent{
   onResize(event){
     event.target.innerWidth; // window width
   }
}

其他回答

在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);
        });
    };
}

希望这对你有所帮助!

在angular CDK中有一个ViewportRuler服务。它在区域外运行,支持方向改变和大小调整。它也适用于服务器端渲染。

@Component({
  selector: 'my-app',
  template: `
    <p>Viewport size: {{ width }} x {{ height }}</p>
  `
})
export class AppComponent implements OnDestroy {
  width: number;
  height: number;
  private readonly viewportChange = this.viewportRuler
    .change(200)
    .subscribe(() => this.ngZone.run(() => this.setSize()));
  constructor(
    private readonly viewportRuler: ViewportRuler,
    private readonly ngZone: NgZone
  ) {
    // Change happens well, on change. The first load is not a change, so we init the values here. (You can use `startWith` operator too.)
    this.setSize();
  }
  // Never forget to unsubscribe!
  ngOnDestroy() {
    this.viewportChange.unsubscribe();
  }

  private setSize() {
    const { width, height } = this.viewportRuler.getViewportSize();
    this.width = width;
    this.height = height;
  }
}

ViewportRuler的Stackblitz示例

好处是,它限制了更改检测周期(它只会在区域中运行回调时触发),而(window:resize)将在每次调用时触发更改检测。

我检查了大部分答案。然后决定查看关于布局的Angular文档。

Angular有自己的观察者来检测不同的大小,而且很容易实现到组件或服务中。

一个简单的例子是:

import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout'; @ component({…}) 类MyComponent { 构造函数(breakpointObserver: breakpointObserver) { breakpointObserver.observe ([ 断点。HandsetLandscape, 断点。HandsetPortrait ])。订阅(result => { If (result.matches) { this.activateHandsetLayout (); } }); } }

希望能有所帮助

我知道很久以前就有人问过这个问题,但现在有更好的方法来做到这一点!我不确定是否有人会看到这个答案。显然你的进口:

import { fromEvent, Observable, Subscription } from "rxjs";

然后在你的组件中:

resizeObservable$: Observable<Event>
resizeSubscription$: Subscription

ngOnInit() {
    this.resizeObservable$ = fromEvent(window, 'resize')
    this.resizeSubscription$ = this.resizeObservable$.subscribe( evt => {
      console.log('event: ', evt)
    })
}

那么一定要取消订阅destroy!

ngOnDestroy() {
    this.resizeSubscription$.unsubscribe()
}

我采取的另一种方法是

import {Component, OnInit} from '@angular/core';
import {fromEvent} from "rxjs";
import {debounceTime, map, startWith} from "rxjs/operators";


function windowSizeObserver(dTime = 300) {
  return fromEvent(window, 'resize').pipe(
    debounceTime(dTime),
    map(event => {
      const window = event.target as Window;

      return {width: window.innerWidth, height: window.innerHeight}
    }),
    startWith({width: window.innerWidth, height: window.innerHeight})
  );
}

@Component({
  selector: 'app-root',
  template: `
    <h2>Window Size</h2>
    <div>
      <span>Height: {{(windowSize$ | async)?.height}}</span>
      <span>Width: {{(windowSize$ | async)?.width}}</span>
    </div>
  `
})
export class WindowSizeTestComponent {
  windowSize$ = windowSizeObserver();
}

这里的windowSizeObserver可以在任何组件中重用