Angular2:观察角度之外的外部变量
Posted
技术标签:
【中文标题】Angular2:观察角度之外的外部变量【英文标题】:Angular2: Watch an external variable outside of angular 【发布时间】:2016-08-18 03:39:33 【问题描述】:我希望能够在 angular2 之外的变量发生变化时进行观察和更新。所以假设我在一个外部 javascript 文件中有这个:
var test = 1;
如何将此变量绑定到组件中的属性?
@Component(
...
)
export class MyComponent
watchy = window.test;
根据this answer.,显然这应该可以工作 但事实并非如此。如果我在控制台中更改变量,该变量不会更新显示在模板中。我错过了什么吗?
【问题讨论】:
【参考方案1】:Angular 仅在异步执行的函数完成时运行更改检测。该函数需要在 Angulars 区域内运行,以便 Angular 识别异步操作。
因为您的变量是从 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 更改检测,因此无需执行更多操作。
【讨论】:
app/app.component.ts(96,12):错误 TS2339:“AppComponent”类型上不存在属性“watchy”。 我猜这是一个 linter 警告。只需在类上声明属性,你就应该很好。 我是新手,从最近两天开始,我收到了这些错误。当我尝试 deciare 时,我遇到了一些其他错误。 piease什么是deciare的正确方法 对不起,我的回答有误。应该是event.detail
,感谢您的提示。
这段代码,如所写,仅适用于按钮/点击/等事件。如果您只是尝试通过事件发送消息(数据),您现在使用window.dispatchEvent(new CustomEvent('test', detail: 'newValue'));
注意,它使用的是 CustomEvent,而不是 Event。 detail
属性只能通过 CustomEvent 获得。您可以查看此 API 和更多详细信息:developer.mozilla.org/en-US/docs/Web/API/CustomEvent/…【参考方案2】:
根据this answer,显然这应该可以工作。
我不确定您是如何得出这个结论的,但无论如何,代码存在更大的问题。这行代码
watchy = window.test;
将创建一个原始类型的组件属性。当那行代码执行时,watchy
将被赋值为1
。 watchy
,因为它是一个原语,在赋值后与window.test
没有关系——它只是获取赋值的window.test
值的副本。因此,如果您随后更改 window.test
的值,JavaScript 将不会更新 watchy
,因此 Angular 更改检测在这里甚至不是一个因素。
如果您希望组件属性链接到全局变量,您可以将原始类型包装在一个对象中:
var myObj = test: 1
export class MyComponent
watchy = window.myObj;
现在,watchy
是一个引用类型,它引用 myObj
对象——它没有得到对象的副本,它只是“指向”它。因此,如果您随后更改 myObj.test
,那么 watchy 将“看到”新值,因为它仍然指向 myObj.test
对象。但是,如果您在 Angular 区域之外更改值,则 Angular 更改检测不会注意到。
如果您在组件模板中显示 test
的值,则需要在 Angular 区域内更改 test
才能运行更改检测并注意到更改。不要在这里重复一堆代码,请参阅Angular 2 How to get Angular to detect changes made outside Angular?
Günter 的回答是另一种方法:在 Angular 内(因此在 Angular 区域内)设置一个事件侦听器,然后在 test
更改时触发该事件。
【讨论】:
【参考方案3】:这永远不会奏效。您需要告诉 Angular2 更新 watchy,有很多方法可以实现这一点,但是将它放在 Angular2 应用程序之外的全局变量中有点奇怪。
例如,您可以在一个函数中设置 watchy,该函数将在组件内元素的点击事件上触发,例如:
@Component(
template: '<div (click)="onClickEvent()"></div>watchy'
)
export class MyComponent
watchy = window.test;
onClickEvent()
this.watchy = window.test;
然后改变var,触发click事件,就可以工作了。
【讨论】:
以上是关于Angular2:观察角度之外的外部变量的主要内容,如果未能解决你的问题,请参考以下文章
Webpack - 在 Angular 2 中调用外部 JS