【问题标题】:Angular2: Watch an external variable outside of angularAngular2:观察角度之外的外部变量
【发布时间】:2016-08-18 03:39:33
【问题描述】:

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

var test = 1;

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

@Component({
   ...
})

export class MyComponent {
    watchy = window.test;
}

根据this answer.,显然这应该可以工作
但事实并非如此。如果我在控制台中更改变量,该变量不会更新显示在模板中。我错过了什么吗?

【问题讨论】:

    标签: angular angular2-changedetection


    【解决方案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 将被赋值为1watchy,因为它是一个原语,在赋值后与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事件,就可以工作了。

      【讨论】:

        猜你喜欢
        • 2015-11-20
        • 1970-01-01
        • 2019-03-24
        • 2016-09-29
        • 2015-11-05
        • 2021-04-22
        • 1970-01-01
        • 2014-10-21
        • 2020-05-11
        相关资源
        最近更新 更多