Angular就使用了这个库, 在它之上建立了ngZone这个模块. 就这样angular在发生异步操作后进行到了变化检测. 使用ngZone: import { ErrorHandler, Injectable, Injector, Inject, NgZone } from '@angular/core'; import : NgZone ) { } private get toastr(): ToastrService { return this.injector.get(ToastrService ); } handleError(error: any): void { this.ngZone.run(() => { this.toastr.error 最后修改app.error-handler.ts: import { ErrorHandler, Injectable, Injector, Inject, NgZone } from '@angular
options.ngZone : undefined; const ngZone = getNgZone(ngZoneOption); const providers: StaticProvider [] = [{provide: NgZone, useValue: ngZone}]; return ngZone.run(() => { const ngZoneInjector _modules, moduleRef)); ngZone !.runOutsideAngular( () => ngZone !. 在获取 ErrorHandler 对象之后,通过调用 ngZone !.runOutsideAngular() 方法,启用异常处理器: ngZone !. runOutsideAngular( () => ngZone !.
解决方法 import { Component, OnInit,NgZone } from '@angular/core'; @Component({ selector: 'app-home', home.component.scss'] }) export class HomeComponent implements OnInit { querys = 2323; constructor(private ngzone :NgZone) { } ngOnInit() { } set() { this.ngzone.run(() => { this.querys = 5;
考虑如下的 Angular 代码: import { Injectable, NgZone } from "@angular/core"; import { interval } from "rxjs" ; @Injectable() export class LocationService { constructor(ngZone: NgZone) { ngZone.runOutsideAngular 退订 subscription 的技巧有很多,下面是一个例子: import { Injectable, NgZone, OnDestroy } from "@angular/core"; import export class LocationService implements OnDestroy { private subscription: Subscription; constructor(ngZone : NgZone) { this.subscription = ngZone.runOutsideAngular(() => interval(1000).subscribe(()
this.host.nativeElement.id, this.editormdConfig); // 创建编辑器 } updateValue(value: string) { this.ngZone.run multi: true }; 最终代码 EditorMdComponent import { Component, ViewChild, Input, AfterViewInit, ElementRef, NgZone ) => { }; onTouched: Function = () => { }; constructor( private el: ElementRef, private ngZone : NgZone ) { } ngAfterViewInit(): void { this.init(); } ngOnDestroy(): void { this.destroy this.host.nativeElement.id, this.editormdConfig); // 创建编辑器 } updateValue(value: string) { this.ngZone.run
值得一提的是这个NgZone。 之前做过一个前端获取ip的需求,封装的getUserIP方法入参是一个回调函数,我在回调函数里调用navigate调用失败,后面也是通过设置ngZone.run()来解决的,这下原理终于搞清楚了,原来是执行上下文的问题
对于setTimeout,addEventListener、promise等都在ngZone中执行(换句话说,就是被zone.js封装重写了),angular并在ngZone中setup了相应的钩子,通知
NgZone.runOutsideAngular — 对无需 UI 更新的长轮询、WebSocket 心跳使用 runOutsideAngular 运行,避免误触发全局变更检测。
class ApplicationRef { changeDetectorRefs:ChangeDetectorRef[] = []; constructor(private zone: NgZone } tick() { this.changeDetectorRefs .forEach((ref) => ref.detectChanges()); } } ngZone
class ApplicationRef { changeDetectorRefs:ChangeDetectorRef[] = []; constructor(private zone: NgZone } tick() { this.changeDetectorRefs .forEach((ref) => ref.detectChanges()); } } ngZone
这个时机是由 NgZone 这个服务去掌控的,它获取到了整个应用的执行上下文,能够对相关的异步事件发生、完成或者异常等进行捕获,然后驱动 Angular 的变化监测机制执行。
Angular2更新机制大体如下: ngZone是对Zone.js的服务封装,Angular2会在每个task执行结束后触发更新。
若要绕过它,启动应用时加上 noop: platformBrowserDynamic().bootstrapModule(AppModule, {ngZone: 'noop'}).then( ref =
完整代码实现如下: // micro-app-angular/src/main.single-spa.ts import { enableProdMode, NgZone } from "@angular getSingleSpaExtraProviders()).bootstrapModule( AppModule ); }, template: "<app-root />", Router, NgZone
NgZone.prototype.run():它将对整个组件树执行更改检测。在这里,引擎盖下的run()将调用tick本身,然后参数将在tick之前获取函数并执行它。