I have an ionic app with the following ui-router setup, where locations state is the parent of 2 states map and favourites. The updates state is a sort of details page that can be access from any state.
.state('locations', {
abstract: false,
cache: true,
url: '/locations',
templateUrl: 'templates/locations.html',
controller: 'LocationsCtrl'
})
.state('locations.favourites', {
cache: true,
url: '/favourites',
templateUrl: 'templates/locations.favourites.html',
controller: 'LocationsFavouritesCtrl'
})
.state('locations.map', {
cache: true,
url: '/map',
templateUrl: 'templates/locations.map.html',
controller: 'LocationsMapCtrl'
})
.state('updates', {
cache: true,
url: '/updates/:place_id',
templateUrl: 'templates/updates.html',
controller: 'UpdatesCtrl',
params: {'place_id': 'undefined'}
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/locations/map');
This is the HTML
<body ng-app="app" animation="slide-left-right-ios7">
<div>
<div>
<ion-nav-bar class="bar-turq">
<ion-nav-back-button class="button-icon icon ion-ios-arrow-back light"></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</div>
</div>
This works perfectly except that the back button on the "updates" state always goes back go locations.map rather than remembering the previous state, ie I might have come from locations.favourites. Is there something fundamentally wrong with my setup?
**
UPDATE:
**
Okay so inside UpdatesCtrl I added this code to check the view history, and no matter where I access the /updates view from, the back view is locations.map
$scope.$on('$ionicView.enter', function() {
console.log($ionicHistory.viewHistory());
}
Remove this params: {'place_id': 'undefined'} or make sure that you pass thru the place_id in $stateparams.place_id
I think that you are ending in an none unknown state (unresolved) and goes to your default state.
You haven't posted your default location route. But I'm assuming that it has this config: $urelRouterProvider.ohterwise('/location.map');
Related
When I make changes to the template from an sub state and I go to the view again the first loaded (so before the template was updated) view is given.
I have tested it with google chrome. internet explorer, microsoft edge all the same problem.
my state
$stateProvider
.state('games', {
abstract: true,
url: "/?username&token",
templateUrl: "games/views/Games.html",
controller: 'GamesController'
})
.state('games.open', {
url: '',
templateUrl: "games/views/GamesOpen.html"
})
.state('games.active', {
url: "/active",
templateUrl: "games/views/GamesActive.html"
})
HTML
<a ui-sref=".open"><button>open games</button></a>
<a ui-sref=".active"><button>active games</button></a>
<div ui-view></div>
The problem seems to be that the views are cached, the transitions work perfectly only I can't view the updated template and always see the first loaded template that was loaded and never the updated version..
A similair question fixes it by adding ?'+ new Date() at the end of the url but this looks like a hack.
you don't have any url in your game.open state: please check that.i guess that is an issue.
When i was creating an app
i used this code :
(well in my case in my certain app )
app.config(function($stateProvider,$urlRouterProvider){
$stateProvider.state('list',{
url:'/list',
templateUrl:'templates/list.html'
});
$stateProvider.state('edit',{
url: '/edit/:noteId',
templateUrl: 'templates/edit.html',
controller:'EditCtrl'
});
$stateProvider.state('add',{
url: '/add',
templateUrl: 'templates/edit.html',
controller:'AddCtrl'
});
$urlRouterProvider.otherwise('/list');
});
and use
a button like this:
New Note
I've been working with Angular for a year or 2 now, but this is my first project using ui-router. I'm running into a few issues with views and sub-views. The app is a standard left-side menu bar, with the views on the right changing depending on what's clicked in the menu bar.
On index.html
<body>
<div ui-view></div>
</body>
In the config.js file, which defines the routes
.state("dashboard", {
url: "/dashboard",
templateUrl: "components/dashboard/dashboard.html",
data: {
pageTitle: "Dashboard",
requiresLogin: false
}
})
.state("dashboard.welcome", {
url: "/welcome",
templateUrl: "components/welcome/welcome.html",
data: {
pageTitle: "Welcome",
requiresLogin: false
}
})
In the dashboard.html file
<div class="dashboard">
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-md-8">
<div ui-view>
The /dashboard path loads correctly, and will load the left-side navigation bar with a blank right side. But changing the state to dashboard.welcome (/welcome) will not load the welcome.html template.
Whenever working with ui-router you need to understand that the concept of states is different from routes. When you define a sub-state, its defined relative to its parent state. In your scenario dashboard.welcome is defined as a child state of dashboard. The routes to substate is relative to the parent and is {parent url}/{child url}. Hence you should use either of the below 2 to route to that state:
Using $state.go change the state by specifying state name
$state.go('dashboard.welcome');
Using $location.path change the route by specifying url
$location.path('/dashboard/welcome');
It sounds like you want links to /welcome to be for state dashboard.welcome. Here is a plunker showing how this can be done. I show two sets of dashboard and welcome states. The first set of states (dashboard & welcome) shows that /dashboard/welcome will bring you to the dashboard.welcome state.
The second set (dashboard2 & welcome2) shows that /welcome will go to state dashboard2.welcome2. I believe this is what you were looking for.
If you hover over the links you can see where they will take you.
https://plnkr.co/edit/AVKPFa?p=info
Nested routes in ui-router get nested urls. I would however recommend using named-views for this kind of structure. You can find more info about it here:
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
The gist of it is: you can specify a named component (ui-view) for your left menu navigation and another one for content, which gives you much more control down the line, because named components can be overwritten in child states or they can keep the default template, depending on your needs.
Example:
.state('root', {
url: '',
abstract: true,
views: {
'header': {
templateUrl: 'templates/partials/header.html',
controller: 'headerCtrl'
},
'logo': {
templateUrl: 'templates/partials/logoView.html'
},
'footer':{
templateUrl: 'templates/partials/footer.html',
controller: 'footerCtrl'
}
}
})
.state('root.login', {
url: '/login',
views: {
'header#': {
template: ''
},
'container#': {
templateUrl: 'templates/login.html',
controller: 'loginController'
}
}
})
.state('root.report', {
url: '/report',
views: {
'container#': {
templateUrl: 'templates/eu_dashboard.html',
controller: 'reportController'
}
}
})
And in your index.html:
<div ui-view="logo"></div>
<div ui-view="header"></div>
<div id="mainView" ui-view="container"></div>
<div ui-view="footer"></div>
I'm using UI-Router for an app but I cant for the life of me understand why the page is blank. None of the template urls are displaying. Here's the plunkr
layout.html
<div ui-view="form"></div>
sdagas
<div ui-view="results"></div>
form
This is the form page
results
Results
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state("index", {
url: "/",
abstract: true,
templateUrl: 'layout.html',
controller: 'MainController',
controllerAs: 'main'
})
.state('index.layout', {
abstract: true,
url: 'layout',
views: {
'form' : {
templateUrl: 'form.html'
},
'results': {}
}
})
.state('index.layout.results', {
url: '/results',
views: {
'results#layout': {
templateUrl: 'results.html'
}
}
});
$urlRouterProvider.otherwise('/');
});
app.controller('MainController', function($state) {
console.log($state);
console.log('hello');
});
Firstly, there is no ng-app declared in your plunker.. You should have ng-app="app" on your html tag.
Secondly, like #Bilal said, you can't have abstract:true on the states you want to transition to.
Moreover, your ui-sref should point to the states:
<a class="brand" ui-sref="index">home</a>
|
<a class="brand" ui-sref="index.layout">ui-router</a>
Here is your updated plunker
I updated a plunker which is working here
The way how we can call state resuts is:
ui-sref
<a class="brand" ui-sref="index.layout.results">
href
<a class="brand" href="#/layout/results">
We can never navigate to state which is abstract. So we cannot go to index or layout
To make the plunker running I also introduced the ng-app="app":
<!DOCTYPE html>
<html ng-app="app">
which does start up the app
Also, because the '/' is otherwise but abstract I used another setting to go to some non abstract state
$urlRouterProvider.when('/', '/layout/results');
$urlRouterProvider.otherwise('/');
And finally (but almost the most important), this is the updated super child state, which does target the named view not in layout but in index state
.state('index.layout.results', {
url: '/results',
views: {
// wrong
//'results#layout': {
// this target is in the super parent
'results#index': {
templateUrl: 'results.html'
}
}
});
Check it here
From ui-router wiki:
An abstract state can have child states but cannot get activated
itself. An 'abstract' state is simply a state that can't be
transitioned to. It is activated implicitly when one of its
descendants are activated.
https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views
You made root state abstract: true so it can't be transitioned.
Update:
ui-sref="/" should contain state name not the url path itself. If you really want to use url path then you should use href="/"
Plunkr
Update:
You also missed ng-app="app" in your html.
<html ng-app="app">
I have 4 states, each representing a different visualization. The first visualization is a map, the second to fourth are pie charts.
The default is the map visualization. I have three icons showing always the other 3 possible visualizations.
Each of the state is actually a nested state. The first state is "root.map", then we have "root.vis1", "root.vis2", and "root.vis3".
When I initially load the default "root.map" visualization, all is fine first. Then I click on an icon, and all works fine, the visualization changes. The URL in the browser becomes "localhost:3000/#/root/vis2" for example. But when I click again, although the visualization correctly changes to the chosen one, I loose the path in the browser, and it becomes "localhost:3000/#".
What could be causing this? I'd like the URL in the browser to always reflect the current URL (so it can be bookmarked or shared).
The state provider config:
$stateProvider
.state('home', {
url: "/home",
templateUrl: "views/home.html",
})
.state('root', {
abstract: true,
url: "/root",
cache: false,
templateUrl: "views/root.html"
})
.state('root.map', {
url: "/map",
cache: false,
templateUrl: "views/map.html",
resolve: {
//some resolve code
}
})
.state('root.vis1', {
url: "/vis1",
cache: false,
templateUrl: "views/vis.html"
})
.state('root.vis2', {
url: "/vis2",
cache: false,
templateUrl: "views/vis.html"
})
.state('root.vis3', {
url: "/vis3",
cache: false,
templateUrl: "views/vis.html"
});
}
The icons:
<a class="inline vis-icons" href="#" ng-click="set_visualization('vis2');"><i class="fa fa-map-marker"></i></a>
The set_visualization function in the controller:
$scope.set_visualization = function(visualization) {
$scope.current_vis = visualization;
$state.transitionTo('root.' + visualization);
return false;
}
Change it to:
<a class="inline vis-icons" href="" ng-click="set_visualization('vis2');">
Or
<a class="inline vis-icons" ng-click="set_visualization('vis2');">
See:
href overrides ng-click in Angular.js
I am using ui-router and state provider to route the pages in my application. I have following states written in state provider.
.state('home', {
url: '/home',
templateUrl: 'public/msStream/stateFiles/stateHome.html',
controller: 'stateHomeController'
})
.state('home.profile', {
url: '/home/profile',
templateUrl: 'public/msStream/views/setting/ProfileBody.html'
})
When I am in home state. /home is added in my URL, but when I switch to home.profile state using $state.go("home.profile), my URL is not changing to /home/profile but HTML page added in templateurl of the same state is getting rendered on front.
I tried adding /profile and /home/profile in the URL of the state but nothing seems to work. What am I missing here?
I created working plunker here
The paren-child states do inherit a lot. Among other things, also the url. So we should not use for child the url part coming from parent.
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'public/msStream/stateFiles/stateHome.html',
controller: 'stateHomeController'
})
.state('home.profile', {
// HERE
// instead of this
// url: '/home/profile',
// we need this
url: '/profile',
templateUrl: 'public/msStream/views/setting/ProfileBody.html'
})
Also very improtant note - parent must contain anchor/target/ui-view for its child:
public/msStream/stateFiles/stateHome.html
<div>
<h2>this is the home</h2>
placeholder for child:
<hr />
<div ui-view=""></div>
</div>
The most important here is the <div ui-view=""></div> - a placeholder for child view (unnamed)
Check it in action here