Angular2中的更改未更新视图

时间:2016-01-04 14:01:39

标签: angular

我已经开始探索Angular2(我将使用Angular1和一些React背景),我遇到了问题。

我想将某些击键绑定到组件中的操作,因此我决定使用Angular2生命周期来绑定/取消绑定操作。

但是,如果我在Mousetrap回调中执行某些操作,它会起作用,但它不会呈现,并且在运行摘要周期之前无法看到更改。

我是否需要明确运行某些内容来更新视图

有人可以帮我弄清楚发生了什么事吗? 任何帮助都将非常感激。

import {Component} from 'angular2/core';
const Mousetrap = require('mousetrap');

@Component({
  template: `<div>
    Video template: Mode {{ mode }}
    <input type="number" [(ngModel)]="mode"/>
  </div>`
})
export class Video {

  public mode: number;

  constructor() {
    this.mode = 0;
  }

  ngOnInit() {

    console.log('hello Video component');
    Mousetrap.bind('d', () => console.log('this.mode=', this.mode));
    Mousetrap.bind('i', () => this.incrementMode()); // doesn't work

    this.incrementMode(); // works
    this.incrementMode(); // works
    setTimeout(() => this.incrementMode(), 4000); // works

  }

  incrementMode() {
    console.log('incMode', this.mode++);
  };

  ngOnDestroy() {
    console.log('bye bye Video component');
    Mousetrap.unbind(['d', 'i']);
  }

}

2 个答案:

答案 0 :(得分:20)

虽然@Günter的答案绝对正确,但我想提出一个不同的解决方案。

Mousetrap库的问题在于它在角度zone 之外创建了实例(请参阅here)。但是要在每次异步事件后触发更改检测,实例应在角度zone 内实例化。您有两种方法可以实现此目的:

  1. 使用依赖注入:
  2. bootstrap(App, [provide(Mousetrap, { useFactory: () => new Mousetrap() }) ]);
    
    // ...
    
    @Component({
      selector: 'my-app', 
      // ...
    })
    export class App {
      constructor(@Inject(Mousetrap) mousetrap) {
        this.mousetrap = mousetrap;
        // ...
      }
      //...
    }
    
    1. 只需在构造函数中创建Mousetrap的实例:
    2. @Component({
        selector: 'my-app', 
        // ...
      })
      export class App {
        constructor() {
          this.mousetrap = new Mousetrap();
          // ...
        }
        //...
      }
      

      在这两种情况下,您都可以使用这样的捕鼠器实例:

      ngOnInit() {
        this.mousetrap.bind('i', () => this.incrementMode()); // It works now!!!
        // ...
      }
      

      现在,您无需在每次ngZone.run()来电中使用bind。在依赖注入的情况下,您还可以在应用程序的任何组件/服务中使用此mousetrap实例(不仅在App组件中)。

      this plunk。我在那里使用依赖注入。

答案 1 :(得分:9)

如果MouseTrap不在Angular之外,您可能需要注入NgZone并运行您的代码,如

  Mousetrap.bind('i', () => this.ngZone.run(() => this.incrementMode()));