Angular2:观察角度以外的外部变量

时间:2016-04-24 21:01:45

标签: angular angular2-changedetection

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

@Component({
   ...
})

export class MyComponent {
    watchy = window.test;
}

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

pdf = Prawn::Document.new(:page_size => "A4", :page_layout => :landscape)

根据this answer.,显然这应该有用 但它并没有。如果我在控制台中更改变量,则变量不会更新显示在模板中。我错过了什么吗?

3 个答案:

答案 0 :(得分:14)

当异步执行函数完成时,Angular仅运行更改检测。该函数需要在Angulars区域内运行,以便角度识别异步操作。

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

您需要手动为Angular调用更改检测以识别已更改的变量。另请参阅Triggering Angular2 change detection manually

例如,如果您可以调度事件而不是仅设置变量,则可以收听事件。

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

调用事件处理程序会自动调用Angulars更改检测,因此无需执行任何操作。

答案 1 :(得分:3)

  

根据this answer,显然这应该有用。

我不确定你是如何得出这个结论的,但无论如何,代码都存在更大的问题。这行代码

watchy = window.test;

将创建一个基本类型的组件属性。执行该行代码时,watchy将被赋值1watchy,因为它是一个原语,在完成赋值后与window.test没有任何关系 - 它只是获得了赋值的window.test值的副本。因此,如果您随后更改window.test的值,JavaScript将不会更新watchy,因此角度变化检测甚至不是此处的因素。

如果要将组件属性链接到全局变量,可以将基本类型包装在对象中:

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

现在,watchy是一个引用类型,它引用了myObj对象 - 它没有得到对象的副本,它只是“指向”它。因此,如果您随后更改myObj.test,那么watchy将“看到”新值,因为它仍然指向myObj.test对象。但是,如果更改Angular区域之外的值,角度变化检测将不会发现。

如果要在组件模板中显示test的值,则需要在Angular区域内更改test,以便运行更改检测并注意更改。请不要在此处重复大量代码,请参阅Angular 2 How to get Angular to detect changes made outside Angular?

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

答案 2 :(得分:0)

这永远不会奏效。你需要告诉Angular2更新watchy,有很多方法可以实现这一点,但是在Angular2应用程序之外的全局var中使用它会有点奇怪。

例如,您可以在一个函数中使用该函数,该函数将在组件中的元素的click事件中触发,如:

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

export class MyComponent {
    watchy = window.test;

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

然后更改var,触发click事件,它将起作用。