Angular2:观察 angular 之外的外部变量

Angular2: Watch an external variable outside of angular

我希望能够在 angular2 之外的变量发生变化时进行观察和更新。所以假设我在外部 javascript 文件中有这个:

var test = 1;

如何将此变量绑定到组件中的 属性?

@Component({
   ...
})

export class MyComponent {
    watchy = window.test;
}

根据
的说法,这显然应该可行 但事实并非如此。如果我更改控制台中的变量,该变量不会更新显示在模板中。我错过了什么吗?

这永远行不通。你需要告诉 Angular2 更新 watchy,有很多方法可以实现这个,但是把它放在 Angular2 应用程序之外的全局变量中有点奇怪。

例如,您可以在一个函数中设置 watchy,该函数将在组件内元素的单击事件上触发,例如:

@Component({
   template: '<div (click)="onClickEvent()"></div>{{watchy}}'
})

export class MyComponent {
    watchy = window.test;

   onClickEvent() {
    this.watchy = window.test;
  }
}

然后改一下var,触发点击事件就可以了

当异步执行的函数完成时,

Angular 仅 运行s 更改检测。该函数需要 运行 在 Angulars 区域内,以便 angular 识别异步操作。

因为您的变量是从 Angulars 区域外更改的。 Angular 不会 运行 更改检测。

您需要手动调用更改检测 Angular 以识别更改的变量。另见

例如,如果您可以分派事件而不只是设置变量,则可以侦听该事件。

window.dispatchEvent(new CustomEvent('test', {detail: 'newValue'}));
@Component({
   ...
})
export class MyComponent {
    @HostListener('window:test', ['$event'])
    testListener(event) {
      this.watchy = event.detail;
    }
}

调用的事件处理程序会自动调用 Angular 的更改检测,因此无需再做任何事情。

Apparently this should just work, according to .

我不确定你是怎么得出这个结论的,但无论如何,代码有一个更大的问题。这行代码

watchy = window.test;

将创建一个原始类型的组件属性。当该行代码执行时,watchy 将被赋值为 1watchy,因为它是原始值,在赋值后与 window.test 没有任何关系——它只是获取赋值的 window.test 值的副本。因此,如果您随后更改 window.test 的值,JavaScript 将不会更新 watchy,因此 Angular 更改检测甚至不是这里的一个因素。

如果您希望组件 属性 链接到全局变量,您可以将原始类型包装在一个对象中:

var myObj = { test: 1}
export class MyComponent {
  watchy = window.myObj;
}

现在,watchy 是一个引用类型,它引用 myObj 对象——它没有得到对象的副本,它只是 "points" 到它。因此,如果您随后更改 myObj.test,那么 watchy 将 "see" 新值,因为它仍然指向 myObj.test 对象。但是,如果您更改 Angular 区域之外的值,Angular 更改检测将不会注意到。

如果要在组件模板中显示 test 的值,则需要将 Angular 区域内的 test 更改为 [=53=,以便进行更改检测] 并注意变化。不要在这里重复一堆代码,请参阅


Günter 的回答是另一种方法:在 Angular 内设置一个事件侦听器(因此在 Angular 区域内),然后在 test 发生变化时触发该事件。