Ionic - [ui.router] can't navigate nested states - angularjs

I've been trying to make this work, I think I'm missing something but I don't know what. I've tried with absolute paths and same problem. Perhaps the way I'm trying to link the states?
Tree view goes like this:
- app
- app.category
- app.category.category-detail
I can navigate from app, to app.category but I can't go any further, here are my routes:
.state('app.category', {
url: "/category?catId",
views: {
'menuContent': {
templateUrl: "templates/category.html",
controller: "CategoryCtrl",
params: ['catId ']
}
}
})
.state('app.category.category-detail', {
url: "/category-detail",
views: {
'menuContent': {
templateUrl: "templates/category-detail.html",
controller: "DirectoryDetailCtrl",
params: [ 'catId' ]
}
}
})
This is my category.html
<ion-view>
<ion-nav-bar class="bar-dark nav-title-slide-ios7 bg-nav" ng-controller="NavCtrl">
<ion-nav-back-button class="button-clear" ng-click="myGoBack()">
<i class="ion-chevron-left blanco negrita"></i>
</ion-nav-back-button>
</ion-nav-bar>
<ion-content class="directory-content padding-3 bg-gris">
<ion-list>
<ion-item ng-repeat="category in categories" class="item-thumbnail-left tarjeta">
<a ui-sref="app.category.category-detail">
{{category.categoryName}}
</a>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
Now, if I inspect this website with Chrome Dev Tools I can see the next link is generated:
<a ui-sref="app.category.category-detail" href="#/app/category/category-detail?catId=1" class="">
Category 1
</a>
But the view is not being loaded, and no error is shown.
category-detail.html
<ion-view>
<ion-nav-bar class="bar-dark nav-title-slide-ios7 bg-nav" ng-controller="NavCtrl">
<ion-nav-back-button class="button-clear" ng-click="myGoBack()">
<i class="ion-chevron-left blanco negrita"></i>
</ion-nav-back-button>
</ion-nav-bar>
<ion-content class="category-content padding-3 bg-gris">
<h1>CATEGORY</h1>
</ion-content>
</ion-view>

There is one issue with params definition and second with view/target naming
I. params: ['catId] issue
Read more about params: {} object for example here:
Angular ui router passing data between states without URL
Notation used above:
params: [ 'catId' ]
is not valid anymore... Now we have more settings arround, e.g. the default value:
params : { cateId : null }
read more here
II. view naming
It also seems, that you are trying to target the same ui-view="menuContent" from 'app.category' and its child state 'app.category.category-detail' ... both with relative naming:
.state('app.category', {
url: "/category?catId",
views: {
'menuContent': { // no # = relative name
...
.state('app.category.category-detail', {
url: "/category-detail",
views: {
'menuContent': {
...
In case, that this target ui-view="menuContent" is defined in the 'app' state, we have to use absolute naming
.state('app.category.category-detail', {
url: "/category-detail",
views: {
'menuContent#app': {
...
The reason is, that name view notation without '#' is realtive and could be expressed as 'viewName#parentState'. So these are the same
.state('app.category', {
url: "/category?catId",
views: {
// relative
'menuContent': {
// absolute - targeting the same ui-view
'menuContent#app': { // this is absolute name
Try to get more here (not about ionic, but the UI-Router stuff behind is the same):
Angularjs ui-router not reaching child controller
Angular UI Router - Nested States with multiple layouts

Related

Navigate from one tab to a nested view of another tab

Is it possible to link from one tab to a nested view in another tab? I've tried two different methods and neither seem to work.
Here's my router config:
.config(function($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
// Each tab has its own nav history stack:
.state('tab.dash', {
url: '/dash',
views: {
'tab-dash': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
.state('tab.chats', {
url: '/chats',
views: {
'tab-chats': {
templateUrl: 'templates/tab-chats.html',
controller: 'ChatsCtrl'
}
}
})
.state('tab.chat-detail', {
url: '/chats/:chatId',
views: {
'tab-chats': {
templateUrl: 'templates/chat-detail.html',
controller: 'ChatDetailCtrl'
}
}
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/tab/dash');
});
In templates/tab-dash.html I have a link to a particular chat detail page:
<ion-view view-title="Dashboard">
<ion-content class="padding">
<h1>My Chats</h1>
Chat #1
</ion-content>
</ion-view>
From here I can navigate the chat detail page, however if I click the "Chats" tab button at the bottom nothing at all happens. I'd like it to bring me to the main Chats page.
Another method I tried was using ui-sref instead of href:
<ion-view view-title="Dashboard">
<ion-content class="padding">
<h1>My Chats</h1>
<a ui-sref="tab.chat-detail{chatId:1}">Chat #1</a>
</ion-content>
</ion-view>
In this case I receive an error Could not resolve 'tab.chat-detail{chatId:1}' from state 'tab.dash'
What's the best way to link to a "detail" view from within another tab? My main is to make sure that clicking the tab button at the bottom always brings me to the parent page for that tab. Right now, in the first example, it gets stuck on the "detail" view.
I got a workaround. I am hiding the tab bar when navigating to nested view of another tab.
And showing it again when user navigates back to the root tab.
To know how to hide and show tab bar programmatically, check this link:-
https://stackoverflow.com/a/45002644/4527624

UI-Router considering url as state

I have my routing defined as below
$stateProvider
('MasterPage', {
url: '/',
templateUrl: 'views/master.html',
})
.state('MasterPage.dashboard', {
url: 'dashboard',
templateUrl: 'views/dash.html',
})
.state('MasterPage.test', {
url: 'test/:id',
templateUrl: 'views/test.html',
})
$urlRouterProvider.otherwise('/');
I have links that allows me to navigate from mainpage to dashboard and then to the test page which works fine. When I navigate to the test page with an id:1234, which makes my url as <HOST>/#/test/1234, and try to refresh it fails. It gives me an error saying:
Cannot resolve state 'MasterPage.test/1234' from 'MasterPage.test'
Why is UI-Router considering the url segment as a state?
Update
I dont have any ui-sref. I am going to the test page by using $state.go('MasterPage.test', {id:1234}).
There is working plunker
This issue is usually related to wrong ui-sref setting
<a ui-sref="MasterPage.test/1234">
we need to split and pass 1) the state name, and 2) state params like this:
<a ui-sref="MasterPage.test({id:1234})">
In case, we want to use href, we just have to concatenate parent and child url definitions (parent '/', child 'test/:id') :
<a href="/test/1234">
EXTEND
So, these states (almost unchanged):
.state('MasterPage', {
url: '/',
templateUrl: 'views/master.html',
})
.state('MasterPage.dashboard', {
url: 'dashboard',
templateUrl: 'views/dash.html',
})
.state('MasterPage.test', {
url: 'test/:id',
templateUrl: 'views/test.html',
})
will work with these links
<a href="#/">
<a href="#/dashboard">
<a href="#/test/1234">
<a href="#/test/9875">
<a ui-sref="MasterPage">
<a ui-sref="MasterPage.dashboard">
<a ui-sref="MasterPage.test({id:2222})">
<a ui-sref="MasterPage.test({id:4444})">
There is working plunker

Ionic back button not working even though ionicHistory back view exists

My ionic back button doesn't do anything when it is being clicked even though, when I print out the version history, it shows that there is a back view. Also for some reason $ionicHistory.enabledBack() is returning false, even though the back view exists and the back view and current view have the same id. Does anyone know how to fix the problem?
Here's a snapshot of the console.
Use ui-router nested views to create states that will replace an ion-nav-view tag in the HTML.
Use ion-view, not ion-nav-view, inside the template html for each nested view.
Example:
Parent (Nav) View HTML:
<ion-nav-view name="navView"></ion-nav-view>
Nested View Level 1 HTML:
<ion-view view-title="Nested View Level 1">
<ion-content></ion-content>
</ion-view>
Nested View Level 2 HTML:
<ion-view view-title="Nested View Level 2">
<ion-content></ion-content>
</ion-view>
ui-router:
$stateProvider
.state('app.navView', {
url: '/nav-view',
views: {
'menuContent': {
templateUrl: 'app/navView.html',
controller: 'NavViewCtrl as vm'
}
}
})
.state('app.nestedViewL1', {
url: '/nested-view-L1',
views: {
'navView': {
templateUrl: 'app/nestedViewL1.html',
controller: 'NestedView1CtrL1 as vm'
}
}
})
.state('app.nestedViewL2', {
url: '/nested-view-L2',
views: {
'navView': {
templateUrl: 'app/nestedViewL2.html',
controller: 'NestedViewL2Ctrl as vm'
}
}
})

Animating onto, and keeping history for a tabbed page

I'm just starting out with Ionic, and have run into a bit of a confusing problem; I have a couple of pages set up (Properties, Test and Xyzzy) set up as follows in the router:
$stateProvider
.state( 'properties', {
url: '/properties',
templateUrl: 'templates/properties.html',
controller: 'PropertiesController'
} )
.state( 'test', {
url: '/test',
abstract: true,
templateUrl: 'templates/test.html',
controller: 'TestController'
} )
.state( 'test.one', {
url: '/one',
views: {
'one-tab': {
templateUrl: 'templates/test-one.html',
controller: 'TestController'
}
}
} )
.state( 'test.two', {
url: '/two',
views: {
'two-tab': {
templateUrl: 'templates/test-two.html',
controller: 'TestController'
}
}
} )
.state( 'xyzzy', {
url: '/xyzzy',
templateUrl: 'templates/xyzzy.html',
controller: 'XyzzyController'
} );
Essentially there are two plain-and-simple pages (Properties and Xyzzy) and one page with tabs (Test). The templates for each page are very simple, and look like this - Properties, Xyzzy and Test
Enough explaining, here's the problem: as you can see, the Xyzzy page has detected that I've navigated to it from the Properties page and gives me a nice back button. It doesn't show up if I go to the Test page though (with the tabs). The code for that is this:
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
Also, when I navigate between Properties and Xyzzy, the page slides left/right in a nice little animation which looks clean. However, when I go into the Test page, there's no transition at all, nor is there when I come out of it.
I've spent a couple of hours looking around Google but can't find anything relevant to transitions in/out of tabbed pages. Any ideas?
Update: Here's the code the views are being built off (in index.html):
<body ng-app="app">
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view animation="slide-left-right"></ion-nav-view>
</body>
for the transition you can use
<ion-nav-view name="main" animation="slide-left-right"></ion-nav-view>
for your pages

Ui-sref is not generating the right url in ionic framework

Hi I have two separate templates named "home.html" & "home.singleLink.html" in templates folder.
home.html looks like this
<ion-list>
<ion-item ng-repeat="link in links">
<a class="button button-clear" ui-sref="home({singleLink: link.name})">{{link.name}}</a>
</ion-item>
<ion-list>
And I want to show "home.singleLink.html" template and vanishes the "home.html" template when a user click on the link what is in ui-sref. I am passing a variable after the "home"
Here is my app.config looks like
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'templates/home.html',
controller: 'linksController'
})
.state('home.singleLink', {
url: '/:singleLink',
templateUrl: 'templates/home.singleLink.html',
controller: 'linksController'
})
As per I know ui-sref will generate a href when a user click in the link. But in my case when I inspect the link I can see a additional href="#/home" along with the ui-sref which is not changing when I click in the link.
Thanks in advance.
We have to change to things. I created working plunker here.
Firstly, the state call:
<ion-list>
<ion-item ng-repeat="link in links">
<a class="button button-clear"
ui-sref="home.singleLink({singleLink: link.name})">{{link.name}}</a>
</ion-item>
</ion-list>
As we can see, the ui-sref is now different
// instead of this:
ui-sref="home({singleLink: link.name})"
// we have to use full state name home.singleLink
ui-sref="home.singleLink({singleLink: link.name})"
Secondly the child state view target
.state('home.singleLink', {
url: '/:singleLink',
views: {
'#': {
templateUrl: 'templates.home.singleLink.html',
controller: 'linksController'
}
}
})
Because our list view (state 'home'), does not have target for child home.singleLink, we have to use absolute naming and place it into root:
views: {
'#': {
Find more here:
View Names - Relative vs. Absolute Names
Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname#statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.
For example, the previous example could also be written as:
.state('report',{
views: {
'filters#': { },
'tabledata#': { },
'graph#': { }
}
})
Check it here, Similar stuff here: Resolving promise with ionic/ui-routing
Since your templates are named home.html and home.singleLink.html I am assuming singleLink is a child of home. Your config should look like this.
$stateProvider
.state('home', {
url: '/home',
views: {
'home': {
templateUrl: 'templates/home.html',
controller: 'linksController'
}
}
})
.state('home.singleLink', {
url: '/singleLink',
views:{
'singleLinkView': {
templateUrl: 'templates/home.singleLink.html',
controller: 'linksController'
}
}
And your home.html shoul look like this
<ion-list>
<ion-item ng-repeat="link in links">
<a class="button button-clear" ui-sref="home.singleLink">{{link.name}}</a>
</ion-item>
<ion-list>

Resources