mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 12:29:55 +08:00
fix(navcontroller): exceptions inside lifecycle events are printed properly
fixes #10974
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { AfterViewInit, Component, ComponentFactoryResolver, ElementRef, forwardRef, Input, Optional, NgZone, Renderer, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { AfterViewInit, Component, ComponentFactoryResolver, ElementRef, ErrorHandler, forwardRef, Input, Optional, NgZone, Renderer, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
import { App } from '../app/app';
|
||||
import { Config } from '../../config/config';
|
||||
@ -74,8 +74,9 @@ export class Nav extends NavControllerBase implements AfterViewInit, RootNode {
|
||||
transCtrl: TransitionController,
|
||||
@Optional() linker: DeepLinker,
|
||||
domCtrl: DomController,
|
||||
errHandler: ErrorHandler
|
||||
) {
|
||||
super(parent, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl);
|
||||
super(parent, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler);
|
||||
|
||||
if (viewCtrl) {
|
||||
// an ion-nav can also act as an ion-page within a parent ion-nav
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ComponentFactoryResolver, Directive, ElementRef, forwardRef, Inject, Input, NgZone, Optional, Renderer, ViewContainerRef } from '@angular/core';
|
||||
import { ComponentFactoryResolver, Directive, ElementRef, ErrorHandler, forwardRef, Inject, Input, NgZone, Optional, Renderer, ViewContainerRef } from '@angular/core';
|
||||
|
||||
import { App } from '../app/app';
|
||||
import { Config } from '../../config/config';
|
||||
@ -31,8 +31,9 @@ export class OverlayPortal extends NavControllerBase {
|
||||
@Optional() linker: DeepLinker,
|
||||
viewPort: ViewContainerRef,
|
||||
domCtrl: DomController,
|
||||
errHandler: ErrorHandler
|
||||
) {
|
||||
super(null, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl);
|
||||
super(null, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler);
|
||||
this._isPortal = true;
|
||||
this._init = true;
|
||||
this.setViewport(viewPort);
|
||||
|
@ -109,7 +109,8 @@ function getNav() {
|
||||
gestureCtrl,
|
||||
trnsCtrl,
|
||||
linker,
|
||||
dom
|
||||
dom,
|
||||
null
|
||||
);
|
||||
return nav;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectorRef, Component, ComponentFactoryResolver, ComponentRef, ElementRef, EventEmitter, Input, NgZone, Optional, Output, Renderer, ViewChild, ViewEncapsulation, ViewContainerRef } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, ComponentFactoryResolver, ComponentRef, ElementRef, ErrorHandler, EventEmitter, Input, NgZone, Optional, Output, Renderer, ViewChild, ViewEncapsulation, ViewContainerRef } from '@angular/core';
|
||||
|
||||
import { App } from '../app/app';
|
||||
import { Config } from '../../config/config';
|
||||
@ -264,9 +264,10 @@ export class Tab extends NavControllerBase {
|
||||
transCtrl: TransitionController,
|
||||
@Optional() private linker: DeepLinker,
|
||||
private _dom: DomController,
|
||||
errHandler: ErrorHandler
|
||||
) {
|
||||
// A Tab is a NavController for its child pages
|
||||
super(parent, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, _dom);
|
||||
super(parent, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, _dom, errHandler);
|
||||
|
||||
this.id = parent.add(this);
|
||||
this._tabsHideOnSubPages = config.getBoolean('tabsHideOnSubPages');
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ComponentRef, Input, ComponentFactoryResolver, ElementRef, EventEmitter, NgZone, ReflectiveInjector, Renderer, ViewContainerRef } from '@angular/core';
|
||||
import { ComponentRef, Input, ComponentFactoryResolver, ElementRef, ErrorHandler, EventEmitter, NgZone, ReflectiveInjector, Renderer, ViewContainerRef } from '@angular/core';
|
||||
|
||||
import { AnimationOptions } from '../animations/animation';
|
||||
import { App } from '../components/app/app';
|
||||
@ -71,7 +71,8 @@ export class NavControllerBase extends Ion implements NavController {
|
||||
public _gestureCtrl: GestureController,
|
||||
public _trnsCtrl: TransitionController,
|
||||
public _linker: DeepLinker,
|
||||
private _domCtrl: DomController
|
||||
private _domCtrl: DomController,
|
||||
private _errHandler: ErrorHandler
|
||||
) {
|
||||
super(config, elementRef, renderer);
|
||||
|
||||
@ -350,7 +351,7 @@ export class NavControllerBase extends Ion implements NavController {
|
||||
if (nav && nav !== this) {
|
||||
throw 'inserted view was already inserted';
|
||||
}
|
||||
if (viewControllers[i]._state === STATE_DESTROYED) {
|
||||
if (view._state === STATE_DESTROYED) {
|
||||
throw 'inserted view was already destroyed';
|
||||
}
|
||||
}
|
||||
@ -857,61 +858,89 @@ export class NavControllerBase extends Ion implements NavController {
|
||||
_willLoad(view: ViewController) {
|
||||
assert(this.isTransitioning(), 'nav controller should be transitioning');
|
||||
|
||||
view._willLoad();
|
||||
try {
|
||||
view._willLoad();
|
||||
} catch (e) {
|
||||
this._errHandler && this._errHandler.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
_didLoad(view: ViewController) {
|
||||
assert(this.isTransitioning(), 'nav controller should be transitioning');
|
||||
assert(NgZone.isInAngularZone(), 'callback should be zoned');
|
||||
|
||||
view._didLoad();
|
||||
this.viewDidLoad.emit(view);
|
||||
this._app.viewDidLoad.emit(view);
|
||||
try {
|
||||
view._didLoad();
|
||||
this.viewDidLoad.emit(view);
|
||||
this._app.viewDidLoad.emit(view);
|
||||
} catch (e) {
|
||||
this._errHandler && this._errHandler.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
_willEnter(view: ViewController) {
|
||||
assert(this.isTransitioning(), 'nav controller should be transitioning');
|
||||
assert(NgZone.isInAngularZone(), 'callback should be zoned');
|
||||
|
||||
view._willEnter();
|
||||
this.viewWillEnter.emit(view);
|
||||
this._app.viewWillEnter.emit(view);
|
||||
try {
|
||||
view._willEnter();
|
||||
this.viewWillEnter.emit(view);
|
||||
this._app.viewWillEnter.emit(view);
|
||||
} catch (e) {
|
||||
this._errHandler && this._errHandler.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
_didEnter(view: ViewController) {
|
||||
assert(this.isTransitioning(), 'nav controller should be transitioning');
|
||||
assert(NgZone.isInAngularZone(), 'callback should be zoned');
|
||||
|
||||
view._didEnter();
|
||||
this.viewDidEnter.emit(view);
|
||||
this._app.viewDidEnter.emit(view);
|
||||
try {
|
||||
view._didEnter();
|
||||
this.viewDidEnter.emit(view);
|
||||
this._app.viewDidEnter.emit(view);
|
||||
} catch (e) {
|
||||
this._errHandler && this._errHandler.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
_willLeave(view: ViewController, willUnload: boolean) {
|
||||
assert(this.isTransitioning(), 'nav controller should be transitioning');
|
||||
assert(NgZone.isInAngularZone(), 'callback should be zoned');
|
||||
|
||||
view._willLeave(willUnload);
|
||||
this.viewWillLeave.emit(view);
|
||||
this._app.viewWillLeave.emit(view);
|
||||
try {
|
||||
view._willLeave(willUnload);
|
||||
this.viewWillLeave.emit(view);
|
||||
this._app.viewWillLeave.emit(view);
|
||||
} catch (e) {
|
||||
this._errHandler && this._errHandler.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
_didLeave(view: ViewController) {
|
||||
assert(this.isTransitioning(), 'nav controller should be transitioning');
|
||||
assert(NgZone.isInAngularZone(), 'callback should be zoned');
|
||||
|
||||
view._didLeave();
|
||||
this.viewDidLeave.emit(view);
|
||||
this._app.viewDidLeave.emit(view);
|
||||
try {
|
||||
view._didLeave();
|
||||
this.viewDidLeave.emit(view);
|
||||
this._app.viewDidLeave.emit(view);
|
||||
} catch (e) {
|
||||
this._errHandler && this._errHandler.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
_willUnload(view: ViewController) {
|
||||
assert(this.isTransitioning(), 'nav controller should be transitioning');
|
||||
assert(NgZone.isInAngularZone(), 'callback should be zoned');
|
||||
|
||||
view._willUnload();
|
||||
this.viewWillUnload.emit(view);
|
||||
this._app.viewWillUnload.emit(view);
|
||||
try {
|
||||
view._willUnload();
|
||||
this.viewWillUnload.emit(view);
|
||||
this._app.viewWillUnload.emit(view);
|
||||
} catch (e) {
|
||||
this._errHandler && this._errHandler.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
hasChildren(): boolean {
|
||||
|
@ -105,7 +105,11 @@ export class ViewController {
|
||||
/** @hidden */
|
||||
@Output() private _emitter: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
constructor(public component?: any, data?: any, rootCssClass: string = DEFAULT_CSS_CLASS) {
|
||||
constructor(
|
||||
public component?: any,
|
||||
data?: any,
|
||||
rootCssClass: string = DEFAULT_CSS_CLASS
|
||||
) {
|
||||
// passed in data could be NavParams, but all we care about is its data object
|
||||
this.data = (data instanceof NavParams ? data.data : (isPresent(data) ? data : {}));
|
||||
|
||||
@ -541,7 +545,7 @@ export class ViewController {
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
_lifecycleTest(lifecycle: string): Promise<any> {
|
||||
_lifecycleTest(lifecycle: string): Promise<boolean> {
|
||||
const instance = this.instance;
|
||||
const methodName = 'ionViewCan' + lifecycle;
|
||||
if (instance && instance[methodName]) {
|
||||
@ -561,16 +565,14 @@ export class ViewController {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
_lifecycle(lifecycle: string) {
|
||||
const instance = this.instance;
|
||||
const methodName = 'ionView' + lifecycle;
|
||||
if (instance && instance[methodName]) {
|
||||
try {
|
||||
instance[methodName]();
|
||||
|
||||
} catch (e) {
|
||||
console.error(`${this.name} ${methodName} error: ${e.message}`);
|
||||
}
|
||||
instance[methodName]();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,7 +423,8 @@ export function mockNavController(): NavControllerBase {
|
||||
gestureCtrl,
|
||||
trnsCtrl,
|
||||
linker,
|
||||
dom
|
||||
dom,
|
||||
null
|
||||
);
|
||||
|
||||
nav._viewInit = function(enteringView: ViewController) {
|
||||
@ -468,7 +469,8 @@ export function mockOverlayPortal(app: App, config: Config, plt: MockPlatform):
|
||||
null,
|
||||
deepLinker,
|
||||
null,
|
||||
dom
|
||||
dom,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
@ -500,7 +502,8 @@ export function mockTab(parentTabs: Tabs): Tab {
|
||||
gestureCtrl,
|
||||
null,
|
||||
linker,
|
||||
dom
|
||||
dom,
|
||||
null
|
||||
);
|
||||
|
||||
tab.load = (opts: any, cb: Function) => {
|
||||
|
Reference in New Issue
Block a user