我已经使用相当基本的JS制作了一个非角度页面,并认为尝试添加学习一些Angular2并将其用于一些新功能是一个很棒的想法。
我的计划是将Angular2组件绑定到旧代码正在更新的对象上,并且我使用Angular2魔法来更新一大块UI。
问题是我无法说服Angular2对外部JS所做的任何更改做出反应。这样做的诀窍是什么?谷歌搜索问题的尝试导致了Angular2的变化检测过程的深入解释,到目前为止还没有帮助。这只是一个糟糕的主意吗?
我找到了一个随机的Angular2 jsfiddle并将其黑了以显示问题。字符串被添加到' window.names',但是在从角度边添加一个字符串之前你不会看到它们:https://jsfiddle.net/byfo3jg3/。代码如下:
var names = ['Joe'];
setTimeout(function() {
names.push("Frank");
}, 1000);
setTimeout(function() {
names.push("Sterve");
}, 2000);
setTimeout(function() {
names.push("Garfield");
}, 3000);
(function() {
var HelloApp,
ListThing;
ListThing = ng
.Component({
selector: 'list-thing',
template: '<ul><li *ng-for="#name of names">{{name}}</li></ul>',
directives: [ng.NgFor]
})
.Class({
constructor: function() {
this.names = window.names;
setTimeout(function() {
this.names.push("Oh hai");
}.bind(this), 10000);
}
});
HelloApp = ng
.Component({
selector: 'hello-app',
template: '<list-thing></list-thing>',
directives: [ListThing]
})
.Class({
constructor: function() {}
});
document.addEventListener('DOMContentLoaded', function() {
ng.bootstrap(HelloApp);
});
}());
答案 0 :(得分:2)
这只是一个糟糕的主意吗?
是
Angular的自动更改检测系统假定数据的更改(您希望组件显示)发生在由Zone.js进行猴子修补的事件处理程序中。因为当这样的事件处理程序触发时,Angular的更改检测将执行(从技术上讲,它将在事件处理程序完成后执行)。
如果希望组件视图自动更新,则必须更改Angular中的绑定数据 - 在Angular区域内。正如@Jigar回答的那样,您可以修改代码以调用angularZone.run(_ => // make changes here)
,但如果必须这样做,您也可以将管理和操作数据的代码移动到服务(或组件,如果逻辑是最小的。)
另请参阅Günter's alternative approach:在Angular中设置一个事件监听器(因此在Angular区域内)。然后,只要在Angular区域外进行更改,就会触发该事件。
答案 1 :(得分:1)
Object* obj = new Obj[rows * cols];
obj[x * cols + y];
应该是在模板内部工作的组件属性:
names
角度不会检测到constructor(){this.names = window.names}
的更改,因此您几乎没有选项:使用window.names
轮询名称或公开全局回调:
setInterval(()=>{this.names = window.names}, 1000)
并从普通js constructor(zone:NgZone)
{
window.notify = ()=> {
zone.run(()=> {
this.names = window.names;
});
}
}
调用它,或使用其他方法调用变更检测。
答案 2 :(得分:1)
您需要将NgZone设置为window对象,然后调用该区域的run function。
请参阅Angular 2 How to get Angular to detect changes made outside Angular? SO问题