Angular2 中的更改不会更新视图 [英] View is not updated on change in Angular2

查看:34
本文介绍了Angular2 中的更改不会更新视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

但是,如果我从 Mousetrap 回调中执行某些操作,它可以工作,但不会呈现并且在运行摘要循环之前更改不可见.

我是否需要显式运行某些东西来更新视图

有人能帮我弄清楚发生了什么吗?任何帮助将不胜感激.

<小时>

从'angular2/core'导入{Component};const 捕鼠器 = require('捕鼠器');@成分({模板:`

视频模板:模式{{模式}}<input type="number" [(ngModel)]="mode"/>

`})导出类视频{公共模式:号码;构造函数(){this.mode = 0;}ngOnInit() {console.log('你好视频组件');Mousetrap.bind('d', () => console.log('this.mode=', this.mode));Mousetrap.bind('i', () => this.incrementMode());//不起作用this.incrementMode();//有效this.incrementMode();//有效setTimeout(() => this.incrementMode(), 4000);//有效}增量模式(){console.log('incMode', this.mode++);};ngOnDestroy() {console.log('再见视频组件');Mousetrap.unbind(['d', 'i']);}}

解决方案

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

Mousetrap 库的问题在于它在 angular "noreferrer">区域(参见 这里).但是要在每个异步事件之后触发更改检测,应该在 angular zone>.您有两种选择来实现这一目标:

  1. 使用依赖注入:

bootstrap(App, [provide(Mousetrap, { useFactory: () => new Mousetrap() }) ]);//...@成分({选择器:'我的应用',//...})出口类应用{构造函数(@Inject(Mousetrap)捕鼠器){this.mousetrap = 捕鼠器;//...}//...}

  1. 只需在构造函数中创建 Mousetrap 的实例:

@Component({选择器:'我的应用',//...})出口类应用{构造函数(){this.mousetrap = new Mousetrap();//...}//...}

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

ngOnInit() {this.mousetrap.bind('i', () => this.incrementMode());//现在可以了!!!//...}

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

请参阅这个 plunk.我在那里使用依赖注入.

I've started exploring Angular2 (I'm coming with Angular1 and a bit of React background) and I got stuck with a problem.

I want to bind certain keystrokes to actions in my component, so I've decided to use Angular2 lifecycle to bind/unbind actions.

However, if I do something from within a Mousetrap callback, it works, but it's not rendered and a change is not visible until a digest cycle is run.

Do I need to run something explicitly to update a view

Could somebody help me to figure out what is going on? Any help would be very appreciated.


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']);
  }

}

解决方案

Although @Günter's answer is absolutely correct I want to propose a different solution.

The problem with Mousetrap library is that it creates its instance outside of the angular zone (see here). But to fire change detection after each async event the instance should be instantiated inside the angular zone. You have two options to achieve this:

  1. Use dependency injection:

bootstrap(App, [provide(Mousetrap, { useFactory: () => new Mousetrap() }) ]);

// ...

@Component({
  selector: 'my-app', 
  // ...
})
export class App {
  constructor(@Inject(Mousetrap) mousetrap) {
    this.mousetrap = mousetrap;
    // ...
  }
  //...
}

  1. Just create instance of Mousetrap inside of the constructor:

@Component({
  selector: 'my-app', 
  // ...
})
export class App {
  constructor() {
    this.mousetrap = new Mousetrap();
    // ...
  }
  //...
}

In both cases you will have the ability to use the mousetrap instance like this:

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

Now you don't need to use ngZone.run() in every bind call. In case of dependency injection you also can use this mousetrap instance in any component/service of your application (not only in App component).

See this plunk. I use dependency injection there.

这篇关于Angular2 中的更改不会更新视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆