当前位置:  开发笔记 > 编程语言 > 正文

Angular2中的更改未更新视图

如何解决《Angular2中的更改未更新视图》经验,为你挑选了2个好方法。

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

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

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

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

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


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

@Component({
  template: `
Video template: Mode {{ mode }}
` }) 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']); } }

alexpods.. 20

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

Mousetrap库的问题是它在角度区域之外创建它的实例(见这里).但是要在每个异步事件之后触发更改检测,实例应该在角度区域实例化.您有两种方法可以实现此目的:

    使用依赖注入:

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

// ...

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

    只需创建Mousetrap构造函数内部的实例:

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

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

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

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

看到这个插件.我在那里使用依赖注入.



1> alexpods..:

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

Mousetrap库的问题是它在角度区域之外创建它的实例(见这里).但是要在每个异步事件之后触发更改检测,实例应该在角度区域实例化.您有两种方法可以实现此目的:

    使用依赖注入:

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

// ...

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

    只需创建Mousetrap构造函数内部的实例:

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

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

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

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

看到这个插件.我在那里使用依赖注入.


@EricMartinez嗯,有太多的js库有绝对疯狂的实现.所以我绝对不能保证这对每个/大多数图书馆都有用.但基本原理很简单:你必须确保在角度区域内调用"异步相关"函数(例如`addEventListener`) - 这就是全部.
@MarkRajcok非常欢迎你.我会说angular2的`ApplicationRef.tick()`等同于angular1的`$ rootScope.$ digest()`,`ngZone.run(cb)`相当于`$ rootScope.$ apply(cb) `和`changeDetectorRef.detectChanges()`相当于`$ scope.$ digest()`.

2> Günter Zöchb..:

如果MouseTrap是Angular之外的东西,你可能需要注入NgZone并运行你的代码

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


感谢有关NgZone的信息,我让它像这样工作:Mousetrap.bind('i',()=> this.ngZone.run(()=> this.incrementMode())); `
推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有