Data binding 对Angular2之外的更改作出反应

Data binding 对Angular2之外的更改作出反应,data-binding,angular,angular2-changedetection,Data Binding,Angular,Angular2 Changedetection,我用相当基本的JS制作了一个无角度的页面,我认为尝试添加学习一些Angular2并将其用于一些新功能将是一个极好的主意 我的计划是将Angular2组件绑定到由旧代码更新的对象,并使用Angular2 magic更新UI的一块 问题是我无法说服Angular2对外部JS中的任何更改做出反应。这样做有什么诀窍?谷歌搜索这个问题的尝试导致了对Angular2的变化检测过程的深入解释,到目前为止,这一过程没有任何帮助。这只是个糟糕的主意吗 我找到了一个随机的Angular2JSFIDLE,并将其砍掉以

我用相当基本的JS制作了一个无角度的页面,我认为尝试添加学习一些Angular2并将其用于一些新功能将是一个极好的主意

我的计划是将Angular2组件绑定到由旧代码更新的对象,并使用Angular2 magic更新UI的一块

问题是我无法说服Angular2对外部JS中的任何更改做出反应。这样做有什么诀窍?谷歌搜索这个问题的尝试导致了对Angular2的变化检测过程的深入解释,到目前为止,这一过程没有任何帮助。这只是个糟糕的主意吗

我找到了一个随机的Angular2JSFIDLE,并将其砍掉以显示问题。字符串已添加到“window.names”中,但只有从角度添加一个字符串后才能看到它们:。守则如下:

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);
    });
}());
var name=['Joe'];
setTimeout(函数(){
姓名。推送(“弗兰克”);
}, 1000);
setTimeout(函数(){
名称。推送(“Sterve”);
}, 2000);
setTimeout(函数(){
名称。推送(“加菲”);
}, 3000);
(功能(){
var HelloApp,
列表;
ListThing=ng
.组成部分({
选择器:“列出事物”,
模板:“
    {{{name}}
”, 指令:[ng.NgFor] }) .类({ 构造函数:函数(){ this.names=window.names; setTimeout(函数(){ 这个.names.push(“ohhai”); }.bind(本),10000); } }); HelloApp=ng .组成部分({ 选择器:“你好应用程序”, 模板:“”, 指令:[列表内容] }) .类({ 构造函数:函数(){} }); document.addEventListener('DOMContentLoaded',function(){ ng.bootstrap(HelloApp); }); }());
名称
应为组件属性,以便在模板内工作:

constructor(){this.names = window.names}
angular不会检测到对
window.names
的更改,因此您只有很少的选项:使用
setInterval(()=>{this.names=window.names},1000)轮询名称
或公开全局回调:

constructor(zone:NgZone) 
{
   window.notify = ()=> {
        zone.run(()=> { 
                this.names = window.names;
        });
   }
 }

并从普通js
窗口调用它。notify()
或使用其他方法调用更改检测。

名称应为组件属性,以便在模板内工作:

constructor(){this.names = window.names}
angular不会检测到对
window.names
的更改,因此您只有很少的选项:使用
setInterval(()=>{this.names=window.names},1000)轮询名称
或公开全局回调:

constructor(zone:NgZone) 
{
   window.notify = ()=> {
        zone.run(()=> { 
                this.names = window.names;
        });
   }
 }

然后从普通js
window.notify()
调用它,或者使用其他方法调用更改检测。

需要将NgZone设置为window对象,然后调用区域的run函数


请参阅SO问题

您需要将NgZone设置为window对象,然后调用该区域的run函数

请参阅上述问题

这只是个糟糕的主意吗

Angular的自动更改检测系统假设对数据(您希望组件显示)的更改发生在由Zone.js进行猴子修补的事件处理程序中。因为Angular的更改检测将在此类事件处理程序触发时执行(从技术上讲,它将在事件处理程序完成后执行)

如果希望零部件视图自动更新,则必须更改角度区域内的绑定数据。正如@Jigar所回答的,您可以修改代码以调用
angularZone.run(=>//在此处进行更改)
,但如果必须这样做,您还可以将管理和操作数据的代码移动到服务(或组件,如果逻辑最小)

另请参见:在Angular(角度区域)内设置事件侦听器。然后在角度区域之外进行更改时触发该事件

这只是个糟糕的主意吗

Angular的自动更改检测系统假设对数据(您希望组件显示)的更改发生在由Zone.js进行猴子修补的事件处理程序中。因为Angular的更改检测将在此类事件处理程序触发时执行(从技术上讲,它将在事件处理程序完成后执行)

如果希望零部件视图自动更新,则必须更改角度区域内的绑定数据。正如@Jigar所回答的,您可以修改代码以调用
angularZone.run(=>//在此处进行更改)
,但如果必须这样做,您还可以将管理和操作数据的代码移动到服务(或组件,如果逻辑最小)


另请参见:在Angular(角度区域)内设置事件侦听器。然后在角度区域之外进行更改时触发该事件。

我不建议这样做,除非您必须这样做!否则,查看可观察对象并订阅组件中该阵列上的更改,在发生更改时更新组件阵列。我不建议这样做,除非您必须这样做!否则,查看可观察对象并订阅组件中该数组上的更改,在出现更改时更新组件数组。
notify()
想法将不起作用,因为您将从角度区域之外调用
notify()
,因此更改检测将不会运行。Test fiddle:然后您可以相当容易地添加
区域。运行
来通知方法。
notify()
想法将不起作用,因为您将从角度区域之外调用
notify()
,所以更改检测将不会运行。测试小提琴:然后你可以相当容易地添加
区域。运行
来通知方法。虽然我决定听从马克的建议,基本上尝试将我的更多应用程序转换成Angular2,而不是绕开它,但我认为这是第一个指向问题的答案