如何使用角度跟踪窗口对象上的变化?

时间:2018-07-30 21:34:32

标签: angular

我需要为VR系统构建页面。这以一种非常奇怪的方式起作用:在VR环境中运行的浏览器会注入一个名为zData的对象。

因此,如果我在控制台上键入window,它将列出与窗口相关的所有内容,例如导航器,焦点,屏幕-以及一个附加对象:zData

我需要观察window.zData并跟踪更改。

因此,由于我无法在此处复制此内容,因此假装zData不存在。假设我需要跟踪window的innerWidth值。因此,每次缩小窗口或缩小查看端口时,都必须触发。

我需要类似的东西:

 window.innerWidth.subscribe((oldValue,newValue) => {
  console.log('old', oldValue);
  console.log('new', newValue);
 });

如果我有一个跟踪innerWidth的解决方案,我相信我可以使用相同的方法来跟踪我的zData。如何存档?

谢谢!

1 个答案:

答案 0 :(得分:1)

当前无法跟踪Angular中超出组件/服务/指令范围的对象变量的变化,包括全局变量和窗口变量。

您可能拥有的最接近的解决方案是使用间隔计时器在变量上实现自己的监视,并跟踪最后检查的值并将其与当前值进行比较。如果您需要在多个地方使用它,甚至可以在服务中实现它。

import { OnInit, OnDestroy } from '@angular/core';
import { Subject, Observable } from 'rxjs';

export interface CheckResult {
    oldValue: object;
    newValue: object;
}

export class ZDataCheckerService implements OnInit, OnDestroy {
    private checker: Subject<CheckResult>;
    public checker$: Observable<CheckResult>;
    private previousValue: object;
    private interval: number;
    private readonly TIMER = 500;


    constructor() {
        this.checker = new Subject<CheckResult>();
        this.checker$ = this.checker.asObservable();
    }

    ngOnInit(): void {
        this.interval = window.setInterval(() => {
            if (this.isDifferent()) {
                this.checker.next({ oldValue: this.previousValue, newValue: window.zData });
            }
            this.previousValue = { ...window.zData };
        }, this.TIMER);
    }

    ngOnDestroy(): void {
        if (typeof this.interval !== 'undefined') {
            window.clearInterval(this.interval);
        }
    }

    private isDifferent(): boolean {
        // Check previous value vs current value using preferred method
        return JSON.stringify(window.zData) !== JSON.stringify(this.previousValue);
    }
}

您必须将计时器设置为想要检查的频率,然后可以通过以下方式订阅它:

this.zDataCheckerService.checker$.subscribe({ oldValue, newValue } => {
    // Do whatever
});