我希望能够在angular2之外的变量发生变化时观察和更新。所以,让我说我在外部javascript文件中有这个:
@Component({
...
})
export class MyComponent {
watchy = window.test;
}
如何将此变量绑定到组件中的属性?
pdf = Prawn::Document.new(:page_size => "A4", :page_layout => :landscape)
根据this answer.,显然这应该有用 但它并没有。如果我在控制台中更改变量,则变量不会更新显示在模板中。我错过了什么吗?
答案 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
将被赋值1
。 watchy
,因为它是一个原语,在完成赋值后与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事件,它将起作用。