mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
refactor(router): separate nav and router-outlet into two seperate directives
This commit is contained in:
48
packages/angular/src/directives/ion-nav.ts
Normal file
48
packages/angular/src/directives/ion-nav.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import {
|
||||
ComponentFactoryResolver,
|
||||
Directive,
|
||||
ElementRef,
|
||||
Injector,
|
||||
Type,
|
||||
} from '@angular/core';
|
||||
|
||||
|
||||
import { FrameworkDelegate } from '@ionic/core';
|
||||
|
||||
import { AngularComponentMounter, AngularEscapeHatch } from '..';
|
||||
|
||||
let id = 0;
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-nav',
|
||||
})
|
||||
export class IonNav implements FrameworkDelegate {
|
||||
|
||||
constructor(
|
||||
public elementRef: ElementRef,
|
||||
protected angularComponentMounter: AngularComponentMounter,
|
||||
protected cfr: ComponentFactoryResolver,
|
||||
protected injector: Injector) {
|
||||
|
||||
this.elementRef.nativeElement.delegate = this;
|
||||
|
||||
}
|
||||
|
||||
attachViewToDom(elementOrContainerToMountTo: HTMLIonNavElement,
|
||||
elementOrComponentToMount: Type<any>,
|
||||
data?: any,
|
||||
classesToAdd?: string[],
|
||||
escapeHatch: AngularEscapeHatch = {}): Promise<any> {
|
||||
|
||||
// wrap whatever the user provides in an ion-page
|
||||
const cfr = escapeHatch.cfr || this.cfr;
|
||||
const injector = escapeHatch.injector || this.injector;
|
||||
return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo,
|
||||
null, elementOrComponentToMount, cfr, injector, data, classesToAdd);
|
||||
}
|
||||
|
||||
removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement) {
|
||||
return this.angularComponentMounter.removeViewFromDom(parentElement, childElement);
|
||||
}
|
||||
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
import { Directive, HostListener, Input } from '@angular/core';
|
||||
|
||||
|
||||
import { MenuController } from '../providers/menu-controller';
|
||||
|
||||
/**
|
||||
* @name MenuToggle
|
||||
* @description
|
||||
* The `menuToggle` directive can be placed on any button to toggle a menu open or closed.
|
||||
* If it is added to the [NavBar](../../toolbar/Navbar) of a page, the button will only appear
|
||||
* when the page it's in is currently a root page. See the [Menu Navigation Bar Behavior](../Menu#navigation-bar-behavior)
|
||||
* docs for more information.
|
||||
*
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* A simple `menuToggle` button can be added using the following markup:
|
||||
*
|
||||
* ```html
|
||||
* <button ion-button menuToggle>Toggle Menu</button>
|
||||
* ```
|
||||
*
|
||||
* To toggle a specific menu by its id or side, give the `menuToggle`
|
||||
* directive a value.
|
||||
*
|
||||
* ```html
|
||||
* <button ion-button menuToggle="right">Toggle Right Menu</button>
|
||||
* ```
|
||||
*
|
||||
* If placing the `menuToggle` in a navbar or toolbar, it should be
|
||||
* placed as a child of the `<ion-navbar>` or `<ion-toolbar>`, and not in
|
||||
* the `<ion-buttons>` element:
|
||||
*
|
||||
* ```html
|
||||
* <ion-header>
|
||||
*
|
||||
* <ion-navbar>
|
||||
* <ion-buttons start>
|
||||
* <button ion-button>
|
||||
* <ion-icon name="contact"></ion-icon>
|
||||
* </button>
|
||||
* </ion-buttons>
|
||||
* <button ion-button menuToggle>
|
||||
* <ion-icon name="menu"></ion-icon>
|
||||
* </button>
|
||||
* <ion-title>
|
||||
* Title
|
||||
* </ion-title>
|
||||
* <ion-buttons end>
|
||||
* <button ion-button (click)="doClick()">
|
||||
* <ion-icon name="more"></ion-icon>
|
||||
* </button>
|
||||
* </ion-buttons>
|
||||
* </ion-navbar>
|
||||
*
|
||||
* </ion-header>
|
||||
* ```
|
||||
*
|
||||
* Similar to `<ion-buttons>`, the `menuToggle` can be positioned using
|
||||
* `start`, `end`, `left`, or `right`:
|
||||
*
|
||||
* ```html
|
||||
* <ion-toolbar>
|
||||
* <button ion-button menuToggle right>
|
||||
* <ion-icon name="menu"></ion-icon>
|
||||
* </button>
|
||||
* <ion-title>
|
||||
* Title
|
||||
* </ion-title>
|
||||
* <ion-buttons end>
|
||||
* <button ion-button (click)="doClick()">
|
||||
* <ion-icon name="more"></ion-icon>
|
||||
* </button>
|
||||
* </ion-buttons>
|
||||
* </ion-toolbar>
|
||||
* ```
|
||||
*
|
||||
* See the [Toolbar API docs](../../toolbar/Toolbar) for more information
|
||||
* on the different positions.
|
||||
*
|
||||
* @demo /docs/demos/src/menu/
|
||||
* @see {@link /docs/components#menus Menu Component Docs}
|
||||
* @see {@link ../../menu/Menu Menu API Docs}
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[menuToggle]',
|
||||
host: {
|
||||
'[hidden]': 'isHidden'
|
||||
}
|
||||
})
|
||||
export class MenuToggle {
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
@Input() menuToggle: string;
|
||||
|
||||
|
||||
constructor(
|
||||
private _menu: MenuController,
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
@HostListener('click')
|
||||
toggle() {
|
||||
const menu = this._menu.get(this.menuToggle);
|
||||
menu && menu.toggle();
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +1,18 @@
|
||||
export { IonicAngularModule } from './module';
|
||||
|
||||
/* Directives */
|
||||
export { MenuToggle } from './directives/menu-toggle';
|
||||
export { IonNav } from './directives/ion-nav';
|
||||
export { VirtualScroll } from './directives/virtual-scroll';
|
||||
export { VirtualItem } from './directives/virtual-item';
|
||||
export { VirtualHeader } from './directives/virtual-header';
|
||||
export { VirtualFooter } from './directives/virtual-footer';
|
||||
|
||||
/* Nav */
|
||||
export { IonNav } from './nav/ion-nav';
|
||||
export { AsyncActivateRoutes } from './nav/router/async-activated-routes';
|
||||
export { OutletInjector } from './nav/router/outlet-injector';
|
||||
export { CustomRouter } from './nav/router/router';
|
||||
export { IonicRouterModule } from './nav/nav-module';
|
||||
/* Router */
|
||||
export { RouterOutlet } from './router/outlet';
|
||||
export { AsyncActivateRoutes } from './router/async-activated-routes';
|
||||
export { OutletInjector } from './router/outlet-injector';
|
||||
export { CustomRouter } from './router/router';
|
||||
export { IonicRouterModule } from './router/router-module';
|
||||
|
||||
/* Providers */
|
||||
export { ActionSheetController, ActionSheetProxy } from './providers/action-sheet-controller';
|
||||
|
@ -11,19 +11,13 @@ import { RadioValueAccessor } from './control-value-accessors/radio-value-access
|
||||
import { SelectValueAccessor } from './control-value-accessors/select-value-accessor';
|
||||
import { TextValueAccessor } from './control-value-accessors/text-value-accessor';
|
||||
|
||||
|
||||
/* Components */
|
||||
|
||||
|
||||
/* Directives */
|
||||
import { MenuToggle } from './directives/menu-toggle';
|
||||
|
||||
import { IonNav } from './directives/ion-nav';
|
||||
import { VirtualScroll } from './directives/virtual-scroll';
|
||||
import { VirtualItem } from './directives/virtual-item';
|
||||
import { VirtualHeader } from './directives/virtual-header';
|
||||
import { VirtualFooter } from './directives/virtual-footer';
|
||||
|
||||
|
||||
/* Providers */
|
||||
import { ActionSheetController } from './providers/action-sheet-controller';
|
||||
import { AlertController } from './providers/alert-controller';
|
||||
@ -39,12 +33,11 @@ import { ToastController } from './providers/toast-controller';
|
||||
@NgModule({
|
||||
declarations: [
|
||||
BooleanValueAccessor,
|
||||
MenuToggle,
|
||||
IonNav,
|
||||
NumericValueAccessor,
|
||||
RadioValueAccessor,
|
||||
SelectValueAccessor,
|
||||
TextValueAccessor,
|
||||
|
||||
VirtualScroll,
|
||||
VirtualItem,
|
||||
VirtualHeader,
|
||||
@ -52,7 +45,7 @@ import { ToastController } from './providers/toast-controller';
|
||||
],
|
||||
exports: [
|
||||
BooleanValueAccessor,
|
||||
MenuToggle,
|
||||
IonNav,
|
||||
NumericValueAccessor,
|
||||
RadioValueAccessor,
|
||||
SelectValueAccessor,
|
||||
@ -61,7 +54,7 @@ import { ToastController } from './providers/toast-controller';
|
||||
VirtualScroll,
|
||||
VirtualItem,
|
||||
VirtualHeader,
|
||||
VirtualFooter,
|
||||
VirtualFooter
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
@ -23,17 +23,15 @@ import {
|
||||
} from '@angular/router';
|
||||
|
||||
|
||||
import { FrameworkDelegate } from '@ionic/core';
|
||||
|
||||
import { AngularComponentMounter, AngularEscapeHatch } from '..';
|
||||
import { OutletInjector } from './router/outlet-injector';
|
||||
import { OutletInjector } from './outlet-injector';
|
||||
|
||||
let id = 0;
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-nav',
|
||||
})
|
||||
export class IonNav implements FrameworkDelegate, OnDestroy, OnInit {
|
||||
export class RouterOutlet implements OnDestroy, OnInit {
|
||||
|
||||
public name: string;
|
||||
public activationStatus = NOT_ACTIVATED;
|
||||
@ -43,7 +41,6 @@ export class IonNav implements FrameworkDelegate, OnDestroy, OnInit {
|
||||
public activatedRouteData: any = {};
|
||||
public activeComponentRef: ComponentRef<any> = null;
|
||||
private id: number = id++;
|
||||
private parent: HTMLElement;
|
||||
|
||||
@Output('activate') activateEvents = new EventEmitter<any>();
|
||||
@Output('deactivate') deactivateEvents = new EventEmitter<any>();
|
||||
@ -58,8 +55,6 @@ export class IonNav implements FrameworkDelegate, OnDestroy, OnInit {
|
||||
protected injector: Injector,
|
||||
@Attribute('name') name: string) {
|
||||
|
||||
this.parent = this.elementRef.nativeElement.parentElement;
|
||||
this.elementRef.nativeElement.delegate = this;
|
||||
this.name = name || PRIMARY_OUTLET;
|
||||
parentContexts.onChildOutletCreated(this.name, this as any);
|
||||
}
|
||||
@ -116,24 +111,6 @@ export class IonNav implements FrameworkDelegate, OnDestroy, OnInit {
|
||||
this.activationStatus = ACTIVATED;
|
||||
});
|
||||
}
|
||||
|
||||
attachViewToDom(elementOrContainerToMountTo: HTMLIonNavElement,
|
||||
elementOrComponentToMount: Type<any>,
|
||||
data?: any,
|
||||
classesToAdd?: string[],
|
||||
escapeHatch: AngularEscapeHatch = {}): Promise<any> {
|
||||
|
||||
// wrap whatever the user provides in an ion-page
|
||||
const cfr = escapeHatch.cfr || this.cfr;
|
||||
const injector = escapeHatch.injector || this.injector;
|
||||
return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo,
|
||||
null, elementOrComponentToMount, cfr, injector, data, classesToAdd);
|
||||
}
|
||||
|
||||
removeViewFromDom(parentElement: HTMLElement, childElement: HTMLElement) {
|
||||
return this.angularComponentMounter.removeViewFromDom(parentElement, childElement);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function activateRoute(navElement: HTMLIonNavElement,
|
@ -28,20 +28,20 @@ import {
|
||||
|
||||
import { IonicAngularModule } from '../module';
|
||||
|
||||
import { PushPopOutletContexts } from './router/push-pop-outlet-contexts';
|
||||
import { CustomRouter } from './router/router';
|
||||
import { IonNav } from './ion-nav';
|
||||
import { flatten } from '../util/util';
|
||||
import { PushPopOutletContexts } from './push-pop-outlet-contexts';
|
||||
import { CustomRouter } from './router';
|
||||
import { RouterOutlet } from './outlet';
|
||||
import { flatten } from './router-utils';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
IonNav
|
||||
RouterOutlet
|
||||
],
|
||||
imports: [
|
||||
IonicAngularModule
|
||||
],
|
||||
exports: [
|
||||
IonNav
|
||||
RouterOutlet
|
||||
]
|
||||
})
|
||||
export class IonicRouterModule {
|
@ -25,10 +25,3 @@ export function removeAllNodeChildren(element: HTMLElement) {
|
||||
export function isString(something: any) {
|
||||
return typeof something === 'string' ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens single-level nested arrays.
|
||||
*/
|
||||
export function flatten<T>(arr: T[][]): T[] {
|
||||
return Array.prototype.concat.apply([], arr);
|
||||
}
|
Reference in New Issue
Block a user