查看未更新在Angular2变化 [英] View is not updated on change in Angular2
问题描述
我已经开始探索Angular2(我与Angular1和一点作出反应的背景来),我卡住了一个问题。
我要绑定某些击键动作在我的组件,所以我决定用Angular2生命周期来绑定/解除绑定操作。
不过,如果我做了什么,从一个捕鼠器回调中,它的工作原理,但它并不是渲染,直到摘要周期运行的变化是不可见的。
我需要显式运行的东西更新视图
有人能帮助我弄清楚是怎么回事?
任何帮助将是非常美联社preciated。
进口{}组件从angular2 /核心;
常量捕鼠器=要求('老鼠夹');@零件({
模板:`< DIV>
视频模板:模式{{模式}}
<输入类型=数字[(ngModel)] =模式/>
< / DIV>`
})
出口类视频{ 公开方式:数; 构造函数(){
this.mode = 0;
} ngOnInit(){ 的console.log('你好视频组件');
Mousetrap.bind('D',()=>的console.log('this.mode =',this.mode));
Mousetrap.bind('我',()=> this.incrementMode()); //不起作用 this.incrementMode(); //作品
this.incrementMode(); //作品
的setTimeout(()=> this.incrementMode(),4000); //作品 } incrementMode(){
的console.log('incMode',this.mode ++);
}; ngOnDestroy(){
的console.log('再见视频组件');
(['D','I'])Mousetrap.unbind;
}}
虽然@君特的回答是绝对正确的我想提出一个不同的解决方案。
与捕鼠器问题
库是它的角的 .js文件/相对=nofollow>区 (见的这里)。但每次异步事件之后触发改变检测的实例应该被实例化的角区一内> 。你有两个选择,以实现这一点:
- 使用依赖注入:
引导程序(App [提供(捕鼠器,{useFactory:()=>新建捕鼠器()})]) ;// ...@零件({
选择:我的应用,
// ...
})
出口类应用{
构造函数(@注入(捕鼠器)捕鼠器){
this.mousetrap =捕鼠器;
// ...
}
// ...
}
<醇开始=2>
捕鼠器实例
构造内: @Component({
选择:我的应用,
// ...
})
出口类应用{
构造函数(){
this.mousetrap =新捕鼠器();
// ...
}
// ...
}
在这两种情况下,你将不得不使用捕鼠器实例,像这样的能力:
ngOnInit(){
this.mousetrap.bind('我',()=&GT; this.incrementMode()); //现在的工作!
// ...
}
现在你不需要使用 ngZone.run()
在每个绑定
调用。在依赖注入的情况下,你也可以使用这个捕鼠器
例如在应用程序(不仅在应用
组件)。
请参阅这个普拉克。我使用依赖注入那里。
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:
- Use dependency injection:
bootstrap(App, [provide(Mousetrap, { useFactory: () => new Mousetrap() }) ]);
// ...
@Component({
selector: 'my-app',
// ...
})
export class App {
constructor(@Inject(Mousetrap) mousetrap) {
this.mousetrap = mousetrap;
// ...
}
//...
}
- 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屋!