Angular 2:啥使服务成为“外部”角度区域?

Posted

技术标签:

【中文标题】Angular 2:啥使服务成为“外部”角度区域?【英文标题】:Angular 2 : what make a service to be "Outside" angular zone?Angular 2:什么使服务成为“外部”角度区域? 【发布时间】:2017-11-07 13:40:57 【问题描述】:

在 *** 上遇到与许多人相同的问题后,我无法理解什么是“外部角度区域”服务?

我已经检查了有关该主题的所有现有问题,这正是我需要问这个问题的原因:

https://github.com/angular/angular/issues/5150 Angular2: view is not updated from inside a subscription https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html http://blog.assaf.co/angular-2-change-detection-zones-and-an-example/

具有默认 ChangeDetectionStrategy 的任何组件中的代码示例: (考虑到视图中引用的 this.value

this.myService.method().subscribe(e => 
    this.value = e;
  );

给定的服务不是“外部角度区域”,视图刷新,另一方面,如果它是“外部角度区域”,视图刷新,除非我们调用 ChangeDetectorRef.detectChanges()。

所以问题是:知道服务是在“角区”内部还是外部的条件是什么?

【问题讨论】:

【参考方案1】:

据我所知,无法检查某物是否在“内部”或“外部”角度区域运行。如果您使用zone.runOutsideAngular,它会在您的区域之外运行。我想到的第二个问题是:你为什么想知道?

【讨论】:

不一定在运行时。我想知道什么样的服务能够自动更新视图,什么样的服务不能。 您将在zone.runOutsideAngular 中运行的所有内容都不会更新视图。【参考方案2】:

看起来我自己找到了我的回复,但我希望这对其他人有帮助:

“外部 Angular 区域”服务是一个未在 Angular 上下文中实例化的类。 许多使用静态访问器的库都容易出现这种情况,这里有一个例子:

http://techqa.info/programming/question/34592857/view-is-not-updated-on-change-in-angular2

我很幸运,它使用的是同一个库。如该外部资源中所述,设法实例化外部库对象将解决视图刷新问题并让该服务成为“内部 Angular 区域”服务。

【讨论】:

【参考方案3】:

你想要的代码是NgZone.isInAngularZone()。这会告诉你它是否在那里执行。

资料来源:在写这篇文章之前,我花了好几个小时阅读 Angular 文档。

此外,您可以将NgZone 注入您的服务并尝试使用this.ngZone.run(() => yourSubscriberCallback()),这应该会有所帮助,尽管我尝试这样做的结果很复杂。

编辑:好的,我设法让我的东西正常工作,让我们看看它是否对你有帮助。

在我的例子中,我使用了一个第三方库,其中包含一个更改监听器。我正在使用 RXJS BehaviorSubject 通过服务将这些更改传播到各种组件,但这些更改没有被拾取。

原来这是因为我在监听器中使用的方法是在 AngularZone 之外执行的。

一开始我是这样做的:

export class Service 

  public BehaviorSubject<Thing> thingSubject = new BehaviorSubject<Thing>(new Thing());

  constructor(private ngZone:NgZone) 
    thirdPartyLibrary.listen(ngZone.run(() => myCallback.bind(_this)));
  

  ...


myCallback 正在做:

myCallback(thing) 
  this.thingSubject.next(thing);

事实证明,这似乎没有在 Angular Zone 内正确执行。我把我的代码改成了这个,它起作用了:

export class Service 

  public BehaviorSubject<Thing> thingSubject = new BehaviorSubject<Thing>(new Thing());

  constructor(private ngZone:NgZone) 
    thirdPartyLibrary.listen(myCallback.bind(_this));
  

  myCallback(thing) 
    this.ngZone.run(() => this.thingSubject.next(thing));
  


之后,我的所有订阅者都在 Angular Zone 内收到了消息并触发了预期的更新。

【讨论】:

以上是关于Angular 2:啥使服务成为“外部”角度区域?的主要内容,如果未能解决你的问题,请参考以下文章

是啥使某物成为“特征对象”?

是啥使某物成为 C++ 中的抽象类 [重复]

Angular 2:未处理的承诺拒绝:没有 AuthService 的提供者! ;区域:角度

Webpack - 在 Angular 2 中调用外部 JS

Angular2:观察角度之外的外部变量

无法导入外部 NPM 包来制作角度库