查看未更新在Angular2变化 [英] View is not updated on change in Angular2

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

问题描述

我已经开始探索Angular2(我与Angular1和一点作出反应的背景来),我卡住了一个问题。

我要绑定某些击键动作在我的组件,所以我决定用Angular2生命周期来绑定/解除绑定操作。

不过,如果我做了什么,从一个捕鼠器回调中,它的工作原理,但它并不是渲染,直到摘要周期运行的变化是不可见的。

我需要显式运行的东西更新视图

有人能帮助我弄清楚是怎么回事?
任何帮助将是非常美联社preciated。


 进口{}组件从angular2 /核心;
常量捕鼠器=要求('老鼠夹');@零件({
  模板:`< D​​IV>
    视频模板:模式{{模式}}
    <输入类型=数字[(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>区 (见的这里)。但每次异步事件之后触发改变检测的实例应该被实例化的 。你有两个选择,以实现这一点:


  1. 使用依赖注入:

引导程序(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:

    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天全站免登陆