fix(angular): ion-back-button

This commit is contained in:
Manu Mtz.-Almeida
2018-03-29 20:46:13 +02:00
parent 7b9a00e433
commit 9c789ceac4
11 changed files with 54 additions and 36 deletions

View File

@ -1,27 +1,19 @@
import { Directive } from '@angular/core'; import { Directive, HostListener, Optional } from '@angular/core';
import { IonRouterOutlet } from './ion-router-outlet';
@Directive({ @Directive({
selector: 'ion-back-button' selector: 'ion-back-button'
}) })
export class IonBackButton { export class IonBackButton {
// constructor( constructor(
// private navCtrl: NavController, @Optional() private routerOutlet: IonRouterOutlet,
// private router ) {}
// @Optional() private routerOutlet: IonRouterOutlet,
// ) {
// routerOutlet.
// }
// @HostListener('click')
// onClick() {
// if(routerOutlet.canGoBack())
// this.navCtrl.setGoback();
// if (!this.routerLink) {
// window.history.back();
// }
// }
@HostListener('click')
onClick() {
if (this.routerOutlet.canGoBack()) {
this.routerOutlet.pop();
}
}
} }

View File

@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
@Injectable() @Injectable()
export class NavController { export class NavController {
private direction = 1; private direction = 0;
private goBack = false; private goBack = false;
private stack: string[] = []; private stack: string[] = [];

View File

@ -1,8 +1,9 @@
import { ComponentFactoryResolver, Directive, ElementRef, Injector} from '@angular/core'; import { ComponentFactoryResolver, Directive, ElementRef, Injector, Input} from '@angular/core';
import { AngularDelegate } from '../providers/angular-delegate'; import { AngularDelegate } from '../providers/angular-delegate';
import { NavOptions, NavParams, TransitionDoneFn, ViewController } from '@ionic/core'; import { ComponentProps, NavOptions, TransitionDoneFn, ViewController } from '@ionic/core';
import { proxyEl } from '../util/util'; import { proxyEl } from '../util/util';
import { inputs } from '../directives/proxies';
@Directive({ @Directive({
@ -10,6 +11,9 @@ import { proxyEl } from '../util/util';
}) })
export class Nav { export class Nav {
@Input() root: any;
@Input() rootParams: any;
constructor( constructor(
private ref: ElementRef, private ref: ElementRef,
cfr: ComponentFactoryResolver, cfr: ComponentFactoryResolver,
@ -17,13 +21,14 @@ export class Nav {
angularDelegate: AngularDelegate, angularDelegate: AngularDelegate,
) { ) {
this.ref.nativeElement.delegate = angularDelegate.create(cfr, injector); this.ref.nativeElement.delegate = angularDelegate.create(cfr, injector);
inputs(this, ref, ['root', 'rootParams']);
} }
push(page: any, params?: NavParams, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> { push(page: any, params?: ComponentProps, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
return proxyEl(this.ref, 'push', page, params, opts, done); return proxyEl(this.ref, 'push', page, params, opts, done);
} }
insert(insertIndex: number, page: any, params?: NavParams, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> { insert(insertIndex: number, page: any, params?: ComponentProps, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
return proxyEl(this.ref, 'insert', insertIndex, page, params, opts, done); return proxyEl(this.ref, 'insert', insertIndex, page, params, opts, done);
} }

View File

@ -1,7 +1,7 @@
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, OnDestroy, OnInit, Optional, Output, ViewContainerRef } from '@angular/core'; import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, OnDestroy, OnInit, Optional, Output, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, ChildrenOutletContexts, PRIMARY_OUTLET, Router } from '@angular/router'; import { ActivatedRoute, ChildrenOutletContexts, PRIMARY_OUTLET, Router } from '@angular/router';
import { StackController } from './router-controller'; import { StackController } from './router-controller';
import { NavController } from '..'; import { NavController } from './ion-nav-controller';
@Directive({ @Directive({
selector: 'ion-router-outlet', selector: 'ion-router-outlet',
@ -31,7 +31,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
) { ) {
this.name = name || PRIMARY_OUTLET; this.name = name || PRIMARY_OUTLET;
parentContexts.onChildOutletCreated(this.name, this as any); parentContexts.onChildOutletCreated(this.name, this as any);
this.stackCtrl = new StackController(stack != null, elementRef.nativeElement, router); this.stackCtrl = new StackController(stack != null, elementRef.nativeElement, router, this.navCtrl);
} }
ngOnDestroy(): void { ngOnDestroy(): void {

View File

@ -1,17 +1,19 @@
import { ComponentRef } from '@angular/core'; import { ComponentRef } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { NavDirection } from '@ionic/core/dist/types/components/nav/nav-util'; import { NavController } from './ion-nav-controller';
import { NavDirection } from '@ionic/core';
export class StackController { export class StackController {
viewsSnapshot: RouteView[] = []; private viewsSnapshot: RouteView[] = [];
views: RouteView[] = []; private views: RouteView[] = [];
constructor( constructor(
private stack: boolean, private stack: boolean,
private containerEl: HTMLIonRouterOutletElement, private containerEl: HTMLIonRouterOutletElement,
private router: Router private router: Router,
private navCtrl: NavController,
) {} ) {}
createView(enteringRef: ComponentRef<any>, route: ActivatedRoute): RouteView { createView(enteringRef: ComponentRef<any>, route: ActivatedRoute): RouteView {
@ -36,13 +38,14 @@ export class StackController {
const leavingView = this.getActive(); const leavingView = this.getActive();
const reused = this.insertView(enteringView); const reused = this.insertView(enteringView);
direction = direction != null ? direction : (reused ? -1 : 1); direction = direction != null ? direction : (reused ? -1 : 1);
await this.transition(enteringView, leavingView, direction); await this.transition(enteringView, leavingView, direction, this.canGoBack(1));
this.cleanup(); this.cleanup();
} }
pop(deep: number) { pop(deep: number) {
const view = this.views[this.views.length - deep - 1]; const view = this.views[this.views.length - deep - 1];
this.navCtrl.setGoback();
this.router.navigateByUrl(view.url); this.router.navigateByUrl(view.url);
} }
@ -77,7 +80,7 @@ export class StackController {
return this.views.length > 0 ? this.views[this.views.length - 1] : null; return this.views.length > 0 ? this.views[this.views.length - 1] : null;
} }
private async transition(enteringView: RouteView, leavingView: RouteView, direction: number) { private async transition(enteringView: RouteView, leavingView: RouteView, direction: number, showGoBack: boolean) {
const enteringEl = enteringView ? enteringView.element : undefined; const enteringEl = enteringView ? enteringView.element : undefined;
const leavingEl = leavingView ? leavingView.element : undefined; const leavingEl = leavingView ? leavingView.element : undefined;
const containerEl = this.containerEl; const containerEl = this.containerEl;
@ -88,7 +91,8 @@ export class StackController {
await containerEl.componentOnReady(); await containerEl.componentOnReady();
await containerEl.commit(enteringEl, leavingEl, { await containerEl.commit(enteringEl, leavingEl, {
duration: direction === 0 ? 0 : undefined, duration: direction === 0 ? 0 : undefined,
direction: direction === -1 ? NavDirection.Back : NavDirection.Forward direction: direction === -1 ? NavDirection.Back : NavDirection.Forward,
showGoBack
}); });
} }
} }

View File

@ -6,6 +6,9 @@ import { PageTwo } from '../page-two/page-two';
template: ` template: `
<ion-header> <ion-header>
<ion-toolbar> <ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>Simple Page One</ion-title> <ion-title>Simple Page One</ion-title>
</ion-toolbar> </ion-toolbar>
</ion-header> </ion-header>

View File

@ -6,6 +6,9 @@ import { ActivatedRoute } from '@angular/router';
template: ` template: `
<ion-header> <ion-header>
<ion-toolbar> <ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>Page Three</ion-title> <ion-title>Page Three</ion-title>
</ion-toolbar> </ion-toolbar>
</ion-header> </ion-header>

View File

@ -7,6 +7,9 @@ import { Location } from '@angular/common';
template: ` template: `
<ion-header> <ion-header>
<ion-toolbar> <ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>Page Two</ion-title> <ion-title>Page Two</ion-title>
</ion-toolbar> </ion-toolbar>
</ion-header> </ion-header>

View File

@ -76,6 +76,7 @@ export class RouterOutlet implements NavOutlet {
easing: opts.easing, easing: opts.easing,
animationCtrl: this.animationCtrl, animationCtrl: this.animationCtrl,
showGoBack: opts.showGoBack,
enteringEl: enteringEl, enteringEl: enteringEl,
leavingEl: leavingEl, leavingEl: leavingEl,
baseEl: this.el, baseEl: this.el,
@ -127,6 +128,7 @@ export interface RouterOutletOptions {
animationBuilder?: AnimationBuilder; animationBuilder?: AnimationBuilder;
duration?: number; duration?: number;
easing?: string; easing?: string;
showGoBack?: boolean;
direction?: NavDirection; direction?: NavDirection;
mode?: 'md' | 'ios'; mode?: 'md' | 'ios';
} }

4
core/src/index.d.ts vendored
View File

@ -59,7 +59,7 @@ export * from './components/modal/modal';
export { ModalController } from './components/modal-controller/modal-controller'; export { ModalController } from './components/modal-controller/modal-controller';
export * from './components/nav/nav'; export * from './components/nav/nav';
export { ViewController } from './components/nav/view-controller'; export { ViewController } from './components/nav/view-controller';
export { NavOptions, TransitionDoneFn} from './components/nav/nav-util'; export { NavDirection, NavOptions, TransitionDoneFn} from './components/nav/nav-util';
export { Note } from './components/note/note'; export { Note } from './components/note/note';
export { PickerColumnCmp } from './components/picker-column/picker-column'; export { PickerColumnCmp } from './components/picker-column/picker-column';
export * from './components/picker/picker'; export * from './components/picker/picker';
@ -110,7 +110,7 @@ export { DomController, RafCallback } from './global/dom-controller';
export { FrameworkDelegate } from './utils/framework-delegate'; export { FrameworkDelegate } from './utils/framework-delegate';
export { OverlayEventDetail } from './utils/overlays'; export { OverlayEventDetail } from './utils/overlays';
export type ComponentRef = HTMLElement | string; export type ComponentRef = Function | HTMLElement | string;
export type ComponentProps = {[key: string]: any}; export type ComponentProps = {[key: string]: any};
export interface Config { export interface Config {

View File

@ -9,7 +9,13 @@ export function attachComponent(delegate: FrameworkDelegate, container: Element,
if (delegate) { if (delegate) {
return delegate.attachViewToDom(container, component, componentProps, cssClasses); return delegate.attachViewToDom(container, component, componentProps, cssClasses);
} }
const el = (typeof component === 'string') ? document.createElement(component) : component; if (typeof component !== 'string' && !(component instanceof HTMLElement)) {
throw new Error('framework delegate is missing');
}
const el = (typeof component === 'string')
? document.createElement(component)
: component;
cssClasses && cssClasses.forEach(c => el.classList.add(c)); cssClasses && cssClasses.forEach(c => el.classList.add(c));
componentProps && Object.assign(el, componentProps); componentProps && Object.assign(el, componentProps);