feat(nav): goBack directive

This commit is contained in:
Manu Mtz.-Almeida
2018-03-27 14:54:43 +02:00
parent 49937eb98c
commit 862e5719c6
10 changed files with 154 additions and 88 deletions

View File

@@ -15,13 +15,14 @@ export function inputs(instance: any, el: ElementRef, props: string[]) {
});
}
const accept = 'accept', activated = 'activated', allowEmptySelection = 'allowEmptySelection', animated = 'animated', autoBlockAll = 'autoBlockAll', autoHide = 'autoHide', autocapitalize = 'autocapitalize', autocomplete = 'autocomplete', autocorrect = 'autocorrect', autofocus = 'autofocus', base = 'base', buttonType = 'buttonType', cancelButtonText = 'cancelButtonText', cancelText = 'cancelText', checked = 'checked', clearInput = 'clearInput', clearOnEdit = 'clearOnEdit', closeDuration = 'closeDuration', color = 'color', cols = 'cols', component = 'component', contentId = 'contentId', data = 'data', debounce = 'debounce', defaultHref = 'defaultHref', detail = 'detail', direction = 'direction', disableScroll = 'disableScroll', disabled = 'disabled', displayFormat = 'displayFormat', doneText = 'doneText', dualKnobs = 'dualKnobs', duration = 'duration', edge = 'edge', expandable = 'expandable', fill = 'fill', fixed = 'fixed', floating = 'floating', forceOverscroll = 'forceOverscroll', from = 'from', fullscreen = 'fullscreen', gestureName = 'gestureName', gesturePriority = 'gesturePriority', highlight = 'highlight', href = 'href', icon = 'icon', inputmode = 'inputmode', interfaceOptions = 'interfaceOptions', ionBackdropTap = 'ionBackdropTap', ionBlur = 'ionBlur', ionCancel = 'ionCancel', ionChange = 'ionChange', ionClear = 'ionClear', ionClick = 'ionClick', ionClose = 'ionClose', ionDecrease = 'ionDecrease', ionDrag = 'ionDrag', ionFocus = 'ionFocus', ionGestureCaptured = 'ionGestureCaptured', ionGestureEnd = 'ionGestureEnd', ionGestureMove = 'ionGestureMove', ionGestureNotCaptured = 'ionGestureNotCaptured', ionGestureStart = 'ionGestureStart', ionIncrease = 'ionIncrease', ionInfinite = 'ionInfinite', ionInput = 'ionInput', ionInputDidLoad = 'ionInputDidLoad', ionInputDidUnload = 'ionInputDidUnload', ionMenuChange = 'ionMenuChange', ionOpen = 'ionOpen', ionPress = 'ionPress', ionPull = 'ionPull', ionRadioDidLoad = 'ionRadioDidLoad', ionRadioDidUnload = 'ionRadioDidUnload', ionRefresh = 'ionRefresh', ionRouteChanged = 'ionRouteChanged', ionRouteDataChanged = 'ionRouteDataChanged', ionRouteRedirectChanged = 'ionRouteRedirectChanged', ionScroll = 'ionScroll', ionScrollEnd = 'ionScrollEnd', ionScrollStart = 'ionScrollStart', ionSelect = 'ionSelect', ionSelectOptionDidLoad = 'ionSelectOptionDidLoad', ionSelectOptionDidUnload = 'ionSelectOptionDidUnload', ionSlideDidChange = 'ionSlideDidChange', ionSlideDrag = 'ionSlideDrag', ionSlideNextEnd = 'ionSlideNextEnd', ionSlideNextStart = 'ionSlideNextStart', ionSlidePrevEnd = 'ionSlidePrevEnd', ionSlidePrevStart = 'ionSlidePrevStart', ionSlideReachEnd = 'ionSlideReachEnd', ionSlideReachStart = 'ionSlideReachStart', ionSlideTouchEnd = 'ionSlideTouchEnd', ionSlideTouchStart = 'ionSlideTouchStart', ionSlideTransitionEnd = 'ionSlideTransitionEnd', ionSlideTransitionStart = 'ionSlideTransitionStart', ionSlideWillChange = 'ionSlideWillChange', ionSplitPaneVisible = 'ionSplitPaneVisible', ionStart = 'ionStart', ionStyle = 'ionStyle', ionSwipe = 'ionSwipe', ionTabButtonDidLoad = 'ionTabButtonDidLoad', ionTabButtonDidUnload = 'ionTabButtonDidUnload', ionTabbarClick = 'ionTabbarClick', knob = 'knob', labelId = 'labelId', layout = 'layout', loadingSpinner = 'loadingSpinner', loadingText = 'loadingText', max = 'max', maxAngle = 'maxAngle', maxEdgeStart = 'maxEdgeStart', maxlength = 'maxlength', mediaQuery = 'mediaQuery', menu = 'menu', menuId = 'menuId', message = 'message', min = 'min', minlength = 'minlength', mode = 'mode', multiple = 'multiple', name = 'name', okText = 'okText', options = 'options', or = 'or', orientation = 'orientation', pager = 'pager', passive = 'passive', pattern = 'pattern', paused = 'paused', persistent = 'persistent', pickerFormat = 'pickerFormat', pin = 'pin', placeholder = 'placeholder', placement = 'placement', platform = 'platform', position = 'position', pressed = 'pressed', pullMax = 'pullMax', pullMin = 'pullMin', pullingIcon = 'pullingIcon', pullingText = 'pullingText', ratio = 'ratio', readonly = 'readonly', refreshingSpinner = 'refreshingSpinner', refreshingText = 'refreshingText', required = 'required', results = 'results', round = 'round', rows = 'rows', scrollEnabled = 'scrollEnabled', scrollEvents = 'scrollEvents', scrollable = 'scrollable', selected = 'selected', selectedText = 'selectedText', show = 'show', showCancelButton = 'showCancelButton', size = 'size', snapbackDuration = 'snapbackDuration', snaps = 'snaps', spellcheck = 'spellcheck', stacked = 'stacked', step = 'step', stopPropagation = 'stopPropagation', strong = 'strong', subTitle = 'subTitle', swipeEnabled = 'swipeEnabled', tappable = 'tappable', threshold = 'threshold', title = 'title', translucent = 'translucent', type = 'type', url = 'url', useHash = 'useHash', useTapClick = 'useTapClick', val = 'val', value = 'value', visible = 'visible', width = 'width', wrap = 'wrap';
const accept = 'accept', activated = 'activated', allowEmptySelection = 'allowEmptySelection', animated = 'animated', autoBlockAll = 'autoBlockAll', autoHide = 'autoHide', autocapitalize = 'autocapitalize', autocomplete = 'autocomplete', autocorrect = 'autocorrect', autofocus = 'autofocus', base = 'base', buttonType = 'buttonType', cancelButtonText = 'cancelButtonText', cancelText = 'cancelText', checked = 'checked', clearInput = 'clearInput', clearOnEdit = 'clearOnEdit', closeDuration = 'closeDuration', color = 'color', cols = 'cols', component = 'component', contentId = 'contentId', data = 'data', debounce = 'debounce', defaultHref = 'defaultHref', detail = 'detail', direction = 'direction', disableScroll = 'disableScroll', disabled = 'disabled', displayFormat = 'displayFormat', doneText = 'doneText', dualKnobs = 'dualKnobs', duration = 'duration', edge = 'edge', expandable = 'expandable', fill = 'fill', fixed = 'fixed', floating = 'floating', forceOverscroll = 'forceOverscroll', from = 'from', fullscreen = 'fullscreen', gestureName = 'gestureName', gesturePriority = 'gesturePriority', goBack = 'goBack', highlight = 'highlight', href = 'href', icon = 'icon', inputmode = 'inputmode', interfaceOptions = 'interfaceOptions', ionBackdropTap = 'ionBackdropTap', ionBlur = 'ionBlur', ionCancel = 'ionCancel', ionChange = 'ionChange', ionClear = 'ionClear', ionClick = 'ionClick', ionClose = 'ionClose', ionDecrease = 'ionDecrease', ionDrag = 'ionDrag', ionFocus = 'ionFocus', ionGestureCaptured = 'ionGestureCaptured', ionGestureEnd = 'ionGestureEnd', ionGestureMove = 'ionGestureMove', ionGestureNotCaptured = 'ionGestureNotCaptured', ionGestureStart = 'ionGestureStart', ionIncrease = 'ionIncrease', ionInfinite = 'ionInfinite', ionInput = 'ionInput', ionInputDidLoad = 'ionInputDidLoad', ionInputDidUnload = 'ionInputDidUnload', ionMenuChange = 'ionMenuChange', ionOpen = 'ionOpen', ionPress = 'ionPress', ionPull = 'ionPull', ionRadioDidLoad = 'ionRadioDidLoad', ionRadioDidUnload = 'ionRadioDidUnload', ionRefresh = 'ionRefresh', ionRouteChanged = 'ionRouteChanged', ionRouteDataChanged = 'ionRouteDataChanged', ionRouteRedirectChanged = 'ionRouteRedirectChanged', ionScroll = 'ionScroll', ionScrollEnd = 'ionScrollEnd', ionScrollStart = 'ionScrollStart', ionSelect = 'ionSelect', ionSelectOptionDidLoad = 'ionSelectOptionDidLoad', ionSelectOptionDidUnload = 'ionSelectOptionDidUnload', ionSlideDidChange = 'ionSlideDidChange', ionSlideDrag = 'ionSlideDrag', ionSlideNextEnd = 'ionSlideNextEnd', ionSlideNextStart = 'ionSlideNextStart', ionSlidePrevEnd = 'ionSlidePrevEnd', ionSlidePrevStart = 'ionSlidePrevStart', ionSlideReachEnd = 'ionSlideReachEnd', ionSlideReachStart = 'ionSlideReachStart', ionSlideTouchEnd = 'ionSlideTouchEnd', ionSlideTouchStart = 'ionSlideTouchStart', ionSlideTransitionEnd = 'ionSlideTransitionEnd', ionSlideTransitionStart = 'ionSlideTransitionStart', ionSlideWillChange = 'ionSlideWillChange', ionSplitPaneVisible = 'ionSplitPaneVisible', ionStart = 'ionStart', ionStyle = 'ionStyle', ionSwipe = 'ionSwipe', ionTabButtonDidLoad = 'ionTabButtonDidLoad', ionTabButtonDidUnload = 'ionTabButtonDidUnload', ionTabbarClick = 'ionTabbarClick', knob = 'knob', labelId = 'labelId', layout = 'layout', loadingSpinner = 'loadingSpinner', loadingText = 'loadingText', max = 'max', maxAngle = 'maxAngle', maxEdgeStart = 'maxEdgeStart', maxlength = 'maxlength', mediaQuery = 'mediaQuery', menu = 'menu', menuId = 'menuId', message = 'message', min = 'min', minlength = 'minlength', mode = 'mode', multiple = 'multiple', name = 'name', okText = 'okText', options = 'options', or = 'or', orientation = 'orientation', pager = 'pager', passive = 'passive', pattern = 'pattern', paused = 'paused', persistent = 'persistent', pickerFormat = 'pickerFormat', pin = 'pin', placeholder = 'placeholder', placement = 'placement', platform = 'platform', position = 'position', pressed = 'pressed', pullMax = 'pullMax', pullMin = 'pullMin', pullingIcon = 'pullingIcon', pullingText = 'pullingText', ratio = 'ratio', readonly = 'readonly', refreshingSpinner = 'refreshingSpinner', refreshingText = 'refreshingText', required = 'required', results = 'results', round = 'round', rows = 'rows', scrollEnabled = 'scrollEnabled', scrollEvents = 'scrollEvents', scrollable = 'scrollable', selected = 'selected', selectedText = 'selectedText', show = 'show', showCancelButton = 'showCancelButton', size = 'size', snapbackDuration = 'snapbackDuration', snaps = 'snaps', spellcheck = 'spellcheck', stacked = 'stacked', step = 'step', stopPropagation = 'stopPropagation', strong = 'strong', subTitle = 'subTitle', swipeEnabled = 'swipeEnabled', tappable = 'tappable', threshold = 'threshold', title = 'title', translucent = 'translucent', type = 'type', url = 'url', useHash = 'useHash', useTapClick = 'useTapClick', val = 'val', value = 'value', visible = 'visible', width = 'width', wrap = 'wrap';
@NgDirective({ selector: 'ion-anchor' })
export class Anchor {
@NgInput() href: string;
@NgInput() goBack: boolean;
constructor(el: ElementRef) {
inputs(this, el, [href]);
inputs(this, el, [href, goBack]);
}
}
@@ -95,10 +96,11 @@ export class Button {
* The color to use from your Sass `$colors` map. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information, see [Theming your App](/docs/theming/theming-your-app).
*/
@NgInput() color: string;
@NgInput() goBack: boolean;
@NgOutput() ionFocus: NgEventEmitter<any>;
@NgOutput() ionBlur: NgEventEmitter<any>;
constructor(el: ElementRef) {
inputs(this, el, [type, href, buttonType, disabled, round, strong, color]);
inputs(this, el, [type, href, buttonType, disabled, round, strong, color, goBack]);
outputs(this, [ionFocus, ionBlur]);
}
}
@@ -603,8 +605,9 @@ export class Item {
* Whether or not this item should be tappable. If true, a button tag will be rendered. Defaults to `false`.
*/
@NgInput() tappable: boolean;
@NgInput() goBack: boolean;
constructor(el: ElementRef) {
inputs(this, el, [color, detail, disabled, href, tappable]);
inputs(this, el, [color, detail, disabled, href, tappable, goBack]);
}
}

View File

@@ -14,6 +14,8 @@ export { PopoverController } from './providers/popover-controller';
export { ToastController } from './providers/toast-controller';
// navigation
export { GoBack } from './navigation/go-back';
export { NavController } from './navigation/ion-nav-controller';
export { Nav } from './navigation/ion-nav';
export { IonRouterOutlet } from './navigation/ion-router-outlet';
export { Tab } from './navigation/ion-tab';

View File

@@ -9,6 +9,8 @@ import { SelectValueAccessor } from './control-value-accessors/select-value-acce
import { TextValueAccessor } from './control-value-accessors/text-value-accessor';
// navigation
import { GoBack } from './navigation/go-back';
import { NavController } from './navigation/ion-nav-controller';
import { Nav } from './navigation/ion-nav';
import { Tab } from './navigation/ion-tab';
import { Tabs } from './navigation/ion-tabs';
@@ -219,6 +221,7 @@ import {
Nav,
Tab,
Tabs,
GoBack,
// router
IonRouterOutlet,
@@ -327,6 +330,7 @@ import {
BooleanValueAccessor,
Nav,
IonRouterOutlet,
GoBack,
Tab,
Tabs,
NumericValueAccessor,
@@ -353,6 +357,7 @@ export class IonicModule {
return {
ngModule: IonicModule,
providers: [
NavController,
AlertController,
ActionSheetController,
Events,

View File

@@ -0,0 +1,17 @@
import { Directive, HostListener } from '@angular/core';
import { NavController } from './ion-nav-controller';
@Directive({
selector: '[goBack]',
})
export class GoBack {
constructor(
private navCtrl: NavController,
) {}
@HostListener('click')
onClick() {
this.navCtrl.setGoback();
}
}

View File

@@ -0,0 +1,17 @@
import { Injectable } from '@angular/core';
@Injectable()
export class NavController {
private goback = false;
setGoback() {
this.goback = true;
}
consumeGoBack() {
const goback = this.goback;
this.goback = false;
return goback;
}
}

View File

@@ -1,5 +1,7 @@
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, OnDestroy, OnInit, Output, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, ChildrenOutletContexts, PRIMARY_OUTLET } from '@angular/router';
import { NavController } from './ion-nav-controller';
import { NavDirection } from '@ionic/core/dist/types/components/nav/nav-util';
@Directive({
selector: 'ion-router-outlet',
@@ -17,11 +19,13 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
@Output('deactivate') deactivateEvents = new EventEmitter<any>();
constructor(
private parentContexts: ChildrenOutletContexts, private location: ViewContainerRef,
private resolver: ComponentFactoryResolver,
private elementRef: ElementRef,
@Attribute('name') name: string,
private changeDetector: ChangeDetectorRef) {
private parentContexts: ChildrenOutletContexts, private location: ViewContainerRef,
private resolver: ComponentFactoryResolver,
private elementRef: ElementRef,
@Attribute('name') name: string,
private changeDetector: ChangeDetectorRef,
private navCtrl: NavController
) {
this.name = name || PRIMARY_OUTLET;
parentContexts.onChildOutletCreated(this.name, this as any);
}
@@ -126,11 +130,13 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
if (enteringEl) {
enteringEl.classList.add('ion-page', 'hide-page');
const navEl = this.elementRef.nativeElement;
const navEl = this.elementRef.nativeElement as HTMLIonRouterOutletElement;
navEl.appendChild(enteringEl);
await navEl.componentOnReady();
await navEl.commit(enteringEl);
await navEl.commit(enteringEl, {
direction: this.navCtrl.consumeGoBack() ? NavDirection.back : NavDirection.forward
});
if (this.deactivated) {
this.deactivated.destroy();