mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 01:52:19 +08:00
fix(angular): adds tabs stack
This commit is contained in:

committed by
Manu MA

parent
d9172b7d68
commit
adae8d4ad1
@ -184,6 +184,11 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
pop(deep = 1) {
|
||||
return this.stackCtrl.pop(deep);
|
||||
}
|
||||
|
||||
getLastUrl() {
|
||||
const active = this.stackCtrl.getActive();
|
||||
return active ? active.fullpath : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function emitEvent(el: HTMLElement) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { ComponentFactoryResolver, Directive, ElementRef, HostListener, Injector, ViewContainerRef } from '@angular/core';
|
||||
import { ComponentFactoryResolver, ContentChild, Directive, ElementRef, HostListener, Injector, ViewContainerRef } from '@angular/core';
|
||||
import { AngularDelegate } from '../../providers/angular-delegate';
|
||||
import { IonRouterOutlet } from './ion-router-outlet';
|
||||
|
||||
|
||||
@Directive({
|
||||
@ -7,19 +8,32 @@ import { AngularDelegate } from '../../providers/angular-delegate';
|
||||
})
|
||||
export class TabDelegate {
|
||||
|
||||
@ContentChild(IonRouterOutlet) outlet?: IonRouterOutlet;
|
||||
|
||||
private nativeEl: HTMLIonTabElement;
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
elementRef: ElementRef,
|
||||
resolver: ComponentFactoryResolver,
|
||||
injector: Injector,
|
||||
angularDelegate: AngularDelegate,
|
||||
location: ViewContainerRef
|
||||
) {
|
||||
elementRef.nativeElement.delegate = angularDelegate.create(resolver, injector, location);
|
||||
this.nativeEl = elementRef.nativeElement;
|
||||
this.nativeEl.delegate = angularDelegate.create(resolver, injector, location);
|
||||
}
|
||||
|
||||
get tab() {
|
||||
return this.nativeEl.tab;
|
||||
}
|
||||
|
||||
getLastUrl() {
|
||||
return this.outlet ? this.outlet.getLastUrl() : undefined;
|
||||
}
|
||||
|
||||
@HostListener('ionRouterOutletActivated', ['$event'])
|
||||
async onNavChanged() {
|
||||
const tab = this.elementRef.nativeElement as HTMLIonTabElement;
|
||||
const tab = this.nativeEl;
|
||||
await tab.componentOnReady();
|
||||
const tabs = tab.closest('ion-tabs');
|
||||
if (tabs) {
|
||||
|
@ -1,25 +1,38 @@
|
||||
import { Directive, ElementRef, HostListener, Optional } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { ContentChildren, Directive, ElementRef, HostListener, Optional, QueryList } from '@angular/core';
|
||||
import { TabDelegate } from './tab-delegate';
|
||||
import { TabButtonClickDetail } from '@ionic/core';
|
||||
import { NavController } from '../../providers';
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-tabs'
|
||||
})
|
||||
export class TabsDelegate {
|
||||
|
||||
@ContentChildren(TabDelegate) tabs: QueryList<TabDelegate>;
|
||||
|
||||
constructor(
|
||||
@Optional() private router: Router,
|
||||
@Optional() private navCtrl: NavController,
|
||||
elementRef: ElementRef
|
||||
) {
|
||||
if (router) {
|
||||
elementRef.nativeElement.useRouter = true;
|
||||
}
|
||||
const nativeEl = elementRef.nativeElement as HTMLIonTabsElement;
|
||||
nativeEl.useRouter = true;
|
||||
}
|
||||
|
||||
urlForTab(tab: string) {
|
||||
const tabDelegate = this.tabs.find(item => item.tab === tab);
|
||||
return tabDelegate ? tabDelegate.getLastUrl() : undefined;
|
||||
}
|
||||
|
||||
@HostListener('ionTabButtonClick', ['$event'])
|
||||
onTabbarClick(ev: UIEvent) {
|
||||
const tabElm: HTMLIonTabButtonElement = ev.detail as any;
|
||||
if (this.router && tabElm && tabElm.href) {
|
||||
this.router.navigateByUrl(tabElm.href);
|
||||
onTabbarClick(ev: any) {
|
||||
const detail = ev.detail as TabButtonClickDetail;
|
||||
const { tab, href, selected } = detail;
|
||||
if (tab && href) {
|
||||
const url = selected
|
||||
? href
|
||||
: this.urlForTab(tab) || href;
|
||||
|
||||
this.navCtrl.navigateBack(url, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -869,7 +869,7 @@ export class TabButton {
|
||||
}
|
||||
|
||||
export declare interface Tabs extends StencilComponents<'IonTabs'> {}
|
||||
@Component({ selector: 'ion-tabs', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
@Component({ selector: 'ion-tabs', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['useRouter'] })
|
||||
export class Tabs {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionNavWillLoad: EventEmitter<CustomEvent>;
|
||||
@ -880,6 +880,7 @@ export class Tabs {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['select', 'setRouteId', 'getRouteId', 'getTab', 'getSelected']);
|
||||
proxyInputs(this, el, ['useRouter']);
|
||||
proxyOutputs(this, el, ['ionChange', 'ionNavWillLoad', 'ionNavWillChange', 'ionNavDidChange']);
|
||||
}
|
||||
}
|
||||
|
2
core/src/components.d.ts
vendored
2
core/src/components.d.ts
vendored
@ -4500,6 +4500,7 @@ export namespace Components {
|
||||
*/
|
||||
'select': (tab: string | HTMLIonTabElement) => Promise<boolean>;
|
||||
'setRouteId': (id: string) => Promise<RouteWrite>;
|
||||
'useRouter': boolean;
|
||||
}
|
||||
interface IonTabsAttributes extends StencilHTMLAttributes {
|
||||
/**
|
||||
@ -4518,6 +4519,7 @@ export namespace Components {
|
||||
* Emitted when the navigation will load a component.
|
||||
*/
|
||||
'onIonNavWillLoad'?: (event: CustomEvent<void>) => void;
|
||||
'useRouter'?: boolean;
|
||||
}
|
||||
|
||||
interface IonText {
|
||||
|
@ -6,5 +6,6 @@ export interface TabBarChangedDetail {
|
||||
|
||||
export interface TabButtonClickDetail {
|
||||
tab: string;
|
||||
selected: boolean;
|
||||
href?: string;
|
||||
}
|
||||
|
@ -74,7 +74,8 @@ export class TabButton implements ComponentInterface {
|
||||
if (!this.disabled) {
|
||||
this.ionTabButtonClick.emit({
|
||||
tab: this.tab,
|
||||
href: this.href
|
||||
href: this.href,
|
||||
selected: this.selected
|
||||
});
|
||||
}
|
||||
ev.preventDefault();
|
||||
|
@ -87,6 +87,13 @@ Using tabs with Angular's router is fairly straight forward. The only additional
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ----------- | ------------ | ----------- | --------- | ------- |
|
||||
| `useRouter` | `use-router` | | `boolean` | `false` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Detail |
|
||||
|
@ -11,7 +11,6 @@ export class Tabs implements NavOutlet {
|
||||
|
||||
private transitioning = false;
|
||||
private leavingTab?: HTMLIonTabElement;
|
||||
private useRouter = false;
|
||||
|
||||
@Element() el!: HTMLStencilElement;
|
||||
|
||||
@ -21,6 +20,9 @@ export class Tabs implements NavOutlet {
|
||||
@Prop({ context: 'config' }) config!: Config;
|
||||
@Prop({ context: 'document' }) doc!: Document;
|
||||
|
||||
/** @internal */
|
||||
@Prop({ mutable: true }) useRouter = false;
|
||||
|
||||
/**
|
||||
* Emitted when the tab changes.
|
||||
*/
|
||||
@ -42,7 +44,9 @@ export class Tabs implements NavOutlet {
|
||||
@Event() ionNavDidChange!: EventEmitter<void>;
|
||||
|
||||
async componentWillLoad() {
|
||||
this.useRouter = !!this.doc.querySelector('ion-router') && !this.el.closest('[no-router]');
|
||||
if (!this.useRouter) {
|
||||
this.useRouter = !!this.doc.querySelector('ion-router') && !this.el.closest('[no-router]');
|
||||
}
|
||||
this.tabs = Array.from(this.el.querySelectorAll('ion-tab'));
|
||||
this.ionNavWillLoad.emit();
|
||||
this.componentWillUpdate();
|
||||
@ -69,9 +73,9 @@ export class Tabs implements NavOutlet {
|
||||
protected onTabClicked(ev: CustomEvent<TabButtonClickDetail>) {
|
||||
const { href, tab } = ev.detail;
|
||||
const selectedTab = this.tabs.find(t => t.tab === tab);
|
||||
if (this.useRouter && href !== undefined) {
|
||||
if (this.useRouter) {
|
||||
const router = this.doc.querySelector('ion-router');
|
||||
if (router) {
|
||||
if (router && href !== undefined) {
|
||||
router.push(href);
|
||||
}
|
||||
} else if (selectedTab) {
|
||||
|
Reference in New Issue
Block a user