I'm struggling to create a basic application in Ionic2 that uses both the side-menu and the tabs navigation. I understand the concepts of the navigation stack and that each tab has its own navigation stack, but I can't grasp the control over the tabs themselves.
The tabs starter template initializes a project with one ion-nav having its rootpage pointing to "rootPage", a property of the #App pointing to a TabsPage class.
<ion-nav id="nav" [root]="rootPage" #content></ion-nav>
The TabsPage class defines 3 properties, one for each page, pointing to their respective classes (each class decorated with #Page). But the TabsPage class itself doesn't seem to have any function, or be injected with a tabs controller and I find little to no documentation on how to acquire a Tabs instance (there are instance methods referenced on http://ionicframework.com/docs/v2/api/components/tabs/Tabs/)
What I managed to do:
Use one tab to control the other.
import {Page, Tabs} from 'ionic-angular';
#Page({
templateUrl: 'build/pages/timeline/timeline.html'
})
export class Timeline {
tabs:Tabs;
constructor(tabs:Tabs) {
this.tabs=tabs;
this.selectTab(2);
}
selectTab(i:number) {
this.tabs.select(i);
}
}
The page above is injected with a Tabs instance, which inherits from NavController. The Tabs instance has the desired select method, and I can point to a different tab (by index, not by name). So in this situation selecting my 'timeline' tab will trigger the constructor, and instead of going to the timeline tab we end up selecting the 2nd tab.
What I would like to do: navigate to a tab with a link in the side-menu.
My side-menu consists of two ion-items, simple buttons with a click listener. In Ionic 1.x I could use a ui-sref or a href to match a certain state, but in Ionic 2 I can't figure out how to control my tabs.
I can access the ion-nav by giving it an id and using app.getComponent('nav'), but I can not target the ion-tabs this way (hoping it would be bound to a Tabs controller instance).
Each ion-tab is a declarative component for a NavController. Basically, each tab is a NavController. For more information on using navigation controllers take a look at the NavController API Docs.
So to access the array of tabs from inside a specific tab page (component) we can set our target path with as simple as :
NavController.parent
Now suppose, we are in a child page of one of our tabs - the component class will be somewhat similar as below:
import { Component } from '#angular/core';
import { NavController, Nav , Tabs } from 'ionic-angular';
// import Tabs
import { Page2} from '../page-2/page-2';
import { Page3} from '../page-3/page-3';
#Component({
templateUrl: 'build/pages/page-1/page1.html'
})
export class Page1 {
tab:Tabs;
// create a class variable to store the reference of the tabs
constructor(public navCtrl: NavController, private nav: Nav) {
this.tab = this.navCtrl.parent;
/*Since Tabs are declarative component of the NavController
- it is accessible from within a child component.
this.tab - actually stores an array of all the tabs defined
in the tab.html / tab component.
*/
}
goToTab2 (){
this.tab.select(1);
// the above line is self explanatory. We are just calling the select() method of the tab
}
goToTab3 (){
this.tab.select(2);
}
}
Hope this helps.
I get this working by following:
app.ts
import {App, IonicApp, Platform} from 'ionic-angular';
#App({
template: '<ion-nav id="nav" [root]="rootPage"></ion-nav>',
})
export class TestApp {
rootPage: any = TabsPage;
constructor(
private platform: Platform,
private app: IonicApp
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
});
}
}
tabs.html
<ion-menu [content]="content">
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<ion-item (click)="openPage(p)" *ngFor="#p of pages;>
<span>{{p.title}}</span>
</ion-item>
</ion-list>
</ion-content>
</ion-menu>
<ion-tabs id="navTabs" #content swipe-back-enabled="false">
<ion-tab [root]="tab1"></ion-tab>
<ion-tab [root]="tab2"></ion-tab>
<ion-tab [root]="tab3"></ion-tab>
</ion-tabs>
tabs.ts
import {Page, NavController, MenuController} from 'ionic-angular';
#Page({
templateUrl: 'build/pages/tabs/tabs.html'
})
export class TabsPage {
pages: Array<{ title: string, component: any }>;
tab1: any = Tab1;
tab2: any = Tab2;
tab3: any = Tab3;
page: any = Page;
constructor(private nav: NavController,
private menu: MenuController) {
this.tab1 = Tab1;
this.tab2 = Tab2;
this.tab3 = Tab3;
this.pages = [
{ title: 'page-menu', component: Page }
];
}
openPage(page) {
// close the menu when clicking a link from the menu
this.menu.close();
// navigate to the new page if it is not the current page
}
}
my solution:
tabs.html : The main tip here is use #tabs
<ion-tabs tabs-only tabsLayout="icon-start" color="light" #tabs>
<ion-tab [root]="tabPage1" tabTitle="Mapa" tabIcon="qi-location arrow">
</ion-tab>
<ion-tab [root]="tabPage2" tabTitle="Em Andamento" tabIcon="qi-th-list" tabBadgeStyle="danger"> </ion-tab>
</ion-tabs>
tabs.ts: Use #ViewChild to bind the wild card used in tabs.html
#Component({
selector: 'page-tabs',
templateUrl: 'tabs.html',
})
export class TabsPage {
#ViewChild('tabs') tabRef: Tabs;
tabPage1: any = HomePage;
tabPage2: any = InProgressPage;
constructor() {
}
switchToHomePage(){
this.tabRef.select(0);
}
switchToInProgressPage(){
this.tabRef.select(1);
}
}
Another page to redirectc : Use #Inject(forwardRef(() => TabsPage)) to get access to parent page methods.
export class AnotherPage {
constructor(#Inject(forwardRef(() => TabsPage)) private tabsPage:TabsPage){}
switchToHome(){
this.tabsPage.switchToHomePage();
}
}
Related
In Tabs navigation page, I couldn't find any back option in ionic2. while using hardware back button the app exits. i have put my code snippets below, any suggestion would be great.
tabs-navigation.html
<ion-tabs >
<ion-tab [root]="tab1Root" tabTitle="Feed" tabIcon="browsers"></ion-tab>
<ion-tab [root]= "tab3Root" tabTitle="Settings" tabIcon="settings"></ion-tab>
</ion-tabs>
tabs.navigation.ts
import {Component} from '#angular/core';
import {Events , App} from "ionic-angular";
import {BrowserPage} from '../browser/browser';
import {SettingsPage} from '../settings/settings';
#Component({
selector: 'tabs-navigation-page',
templateUrl: 'tabs-navigation.html'
})
export class TabsNavigationPage{
tab1Root: any;
tab2Root: any;
constructor(public events: Events , public app: App) {
this.tab1Root = BrowserPage;
this.tab2Root = SettingsPage;
}
}
Following other answer, try a lot of time ald.. no error showing, but cannot click the button. When click the error showing like title.
Tried:
1.download plugin npm install -g typings (nothing happen)
2.add declare var cordova:any; , after add this no error show, cordova can use, but after click the button new error showing...(error in title)
service.html
<ion-content>
<button (click)="launch()" style="width:30%" ion-button color="danger" round>测试</button>
</ion-content>
service.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, Platform} from 'ionic-angular';
import { ServiceDataProvider } from '../../providers/service-data';
declare var cordova:any;
#IonicPage()
#Component({
selector: 'page-service',
templateUrl: 'service.html',
})
export class ServicePage {
users:any;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public serviceData:ServiceDataProvider,
public platform:Platform) {
this.platform = platform;
}
launch(url:any){
this.platform.ready().then(() => {
cordova.InAppBrowser.open(url, "_system", "location=yes");
});
};
}
Make sure you have Cordova in app browser plugin installed, run the below code in terminal in your project root. More often than not, this would be the issue.
cordova plugin add cordova-plugin-inappbrowser
Update:
When running in a browser just make sure you are not using the in app browser.
if(this.platform.is("cordova"))
{
// Run the in app browser code
}
else
{
window.open(encodeURI(url));
}
This is how I solved my error.. and in app browser plugin can run in my project.
html file
<button (click)="launch()" style="width:90%" ion-button color="danger" >button</button>
ts file
launch(){
this.InAppBrowser.create('This is your URL',"_blank","location=no");
}
I have a dashboard page. and this page has two tabs to show recent sales and recent inventory.
When user inters dashboard, loadDashboardItems method is called.
My dashboard.ts
import { Component } from '#angular/core';
import {NavController, NavParams, LoadingController } from 'ionic-angular';
import {Storagehelper} from '../../providers/storagehelper';
import { DashboardrecentsalesPage } from '../dashboardrecentsales/dashboardrecentsales';
import { DashboardrecentinventoryPage } from '../dashboardrecentinventory/dashboardrecentinventory';
import {Webservice} from '../../providers/webservice';
/**
* Generated class for the Dashboard page.
*
* See http://ionicframework.com/docs/components/#navigation for more info
* on Ionic pages and navigation.
*/
#Component({
selector: 'page-dashboard',
templateUrl: 'dashboard.html',
})
export class DashboardPage {
private recentSales;
private recentInventory;
private loading;
private ajaxRequest;
constructor(public navCtrl: NavController, public navParams: NavParams, private storagehelper: Storagehelper, public loadingCtrl: LoadingController, public webservice: Webservice) {
this.loadDashboardItems();
this.recentSales = DashboardrecentsalesPage; //This is the default tab in dashboard page
this.recentInventory = DashboardrecentinventoryPage;
}
ionViewWillLeave(){
if(this.loading) this.loading.dismiss().catch(() => {});
if(this.ajaxRequest!=undefined){
this.ajaxRequest.unsubscribe();
}
}
private loadDashboardItems(){
//HERE API REQUEST IS MADE AND data is saved to Localstorage
}
}
And default tab dashboardrecentsales.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, Tabs } from 'ionic-angular';
import {Storagehelper} from '../../providers/storagehelper';
/**
* Generated class for the Dashboardsummaryitems page.
*
* See http://ionicframework.com/docs/components/#navigation for more info
* on Ionic pages and navigation.
*/
#Component({
selector: 'page-dashboardrecentsales',
templateUrl: 'dashboardrecentsales.html',
})
export class DashboardrecentsalesPage {
private RecentItems;
constructor(public navCtrl: NavController, public navParams: NavParams, private storagehelper: Storagehelper) {
this.getDashboardItems();
}
getDashboardItems(){
this.RecentItems = this.storagehelper.getStorageItem("RecentItems");
//This RecentItems property is used to render view dashboardrecentsales
}
}
Here in dashboard.ts the API request is made and data are saved in LocalStorage
And 'dashboardrecentsales.ts' fetches data from local storage and renders view to show on tab.
PROBLEM
The problem I have is if user is accessing dashboard page for the first time, Even though data are saved in localstorage, the tab page doesn't get any data from localstorage.
It seems Tab is rendered before execution of loadDashboardItems method of dashboard page gets completed.
I tried putting
this.recentSales = DashboardrecentsalesPage; //This is the default tab in dashboard page
this.recentInventory = DashboardrecentinventoryPage;
inside loadDashboardItems method when everything is saved to localstorage, but no tab view was rendered at all.
Can anybody suggest what can I do in this scenario.
For your case, you can make use of ionViewDidLoad() to load your dashboard items. Try something like this,
ionViewDidLoad(){
this.loadDashboardItems();
}
check this documentation to know more about all the predefined NavController methods
Hope that helps!
Anyway I solved it using event.publish and event.subscribe. More info Here
The sample code from the link. I used this logic to refresh the contents.
import { Events } from 'ionic-angular';
// first page (publish an event when a user is created)
constructor(public events: Events) {}
createUser(user) {
console.log('User created!')
events.publish('user:created', user, Date.now());
}
// second page (listen for the user created event after function is called)
constructor(public events: Events) {
events.subscribe('user:created', (user, time) => {
// user and time are the same arguments passed in `events.publish(user, time)`
console.log('Welcome', user, 'at', time);
});
}
I am using documentation
http://ionicframework.com/docs/v2/api/components/navbar/Navbar/
while using this api, i have injected dependency Navbar to my page.I can enable/disable backbutton with API. I wish to capture click on this button and nagivate using backButtonClick(). Can you tell me how to use this method?
You can use Angular's #ViewChild. First, you inject the child component into the one we need to do an interaction:
import { ViewChild } from '#angular/core';
import { Navbar } from 'ionic-angular';
export class MyNavBar {
#ViewChild(Navbar) navbar: Navbar;
}
Then, you can call your backButtonClick method:
this.navbar.backButtonClick = (e: UIEvent) => {
// Print this event to the console
console.log(e);
// Navigate to another page
this.navCtrl.push(AnotherPage);
}
I'm trying to use the Ionic 2 and I'm still struggling with most basic tasks, such as select a tab when the app is loading.
I've tried to inject the Tabs controller and call select on the onPageLoaded event, but to no avail.
Can someone help maybe?
To default to a tab in ionic 2 change the selectedIndex property:
<ion-tabs [selectedIndex]="1">
<ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="rewind"></ion-tab> <!-- Index 0-->
<ion-tab [root]="tab2Root" tabTitle="About" tabIcon="md-time"></ion-tab><!-- Index 1 (Selected)-->
<ion-tab [root]="tab3Root" tabTitle="Contacts" tabIcon="fastforward"></ion-tab><!-- Index 2-->
</ion-tabs>
The About tab will be the selected tab when the page loads.
//importing tabs for manipuling our ion-tabs
import {Tabs} from 'ionic-angular';
#Page({
templateUrl: 'build/pages/page1/page1.html'
})
export class Page1
{
//provide Angular with metadata about things it should inject in the constructor
static get parameters()
{
return [[Tabs]];
}
//after injecting ,passing an instance of [Tabs] in the page constructor
constructor(tab) {
this.tab = tab;
}
//"onPageWillEnter" function fires every time a page becomes the active view.
onPageWillEnter()
{
//make the second tab selected From the first tab (within the current Page 'page1')
// 1 IS the index of the target tab
this.tab.select(1);
}
}
try
var t: Tabs = this.nav.parent;
t.select(index);
In Ionic 3 and angular 4.
import { Tabs } from 'ionic-angular/navigation/nav-interfaces';
#ViewChild('myTabs') tabRef: Tabs; - With in the class about constructor.
this.tabRef.select(0, {}); // In the method where you want set tab.
This is the way to do it in 2022 (Ionic 5)
<ion-tabs #tabs>
<ion-tab-bar slot="bottom">
<ion-tab-button tab="map">
<ion-icon name="map"></ion-icon>
<ion-label>Map</ion-label>
</ion-tab-button>
...
</ion-tab-bar>
<ion-tabs>
Then in your typescript
import { IonTabs } from '#ionic/angular';
#Component({
selector: 'app-some-component',
templateUrl: './some-component.page.html',
styleUrls: ['./some-component.page.scss'],
})
export class SomeComponentPage implements OnInit {
#ViewChild('tabs') tabs: IonTabs;
constructor() {}
ngOnInit() {
this.tabs.select('pre-operative-preparation')
}
}