I have a route definition as follows:
$stateProvider
.state('vehicles', {
url: '/vehicles',
templateUrl: 'foo/bar1.html'
}).state('vehicles.id', {
url: '/{id}',
templateUrl: 'foo/bar3.html'
}).state('vehicles.create', {
url: '/create',
templateUrl: 'foo/bar2.html',
controller: 'VehicleCreateController'
});
I have a button that does
$state.go("vehicles.create");
The problem is, that while the URL changes correctly, the page remains the same. Only after the second click, the correct template appears.
After a hint from my colleague I realized, that it was the state definitions that caused the problem. Reordering the states from "more specific" (URL-wise - i.e. /create) to less specific (/{id}) did the trick. So the thing that was wrong was having the more generic URL /vehicles/{id} before the very similar, but less generic /vehicles/create.
So here's the improved version:
$stateProvider
.state('vehicles', {
url: '/vehicles',
templateUrl: 'foo/bar1.html'
}).state('vehicles.create', {
url: '/create',
templateUrl: 'foo/bar2.html',
controller: 'VehicleCreateController'
}).state('vehicles.id', {
url: '/{id}',
templateUrl: 'foo/bar3.html'
});
use : for your params and ? to make those params optional if you need.
check the below code snippet, for routing with params.
$stateProvider
.state('contacts.detail', {
url: "/contacts/:contactId",
templateUrl: 'contacts.detail.html',
controller: function ($stateParams) {
// If we got here from a url of /contacts/42
expect($stateParams).toBe({contactId: "42"});
}
})
check this for more clear view on routing.
Related
I want to be able to click on the anchor in the #leftDiv and make the UI router template open in the #rightDiv. So, when I click on Hello Plunker 1 in the #leftDiv, I want peopleOne.html to open in the #rightDiv. When I click on Hello Plunker 2, I want peopleTwo.html to replace peopleOne.html in the #rightDiv.
Here is a Plunker - https://plnkr.co/edit/T8RTgea8VccA9mdBABGC?p=preview
Can someone provide insight into why this is not working.
Script.js
var Delivery = angular.module('Delivery', ['ui.router']);
angular
.module('Delivery')
.config(function($stateProvider, $locationProvider) {
$locationProvider.hashPrefix('');
$stateProvider
.state('home', {
url: '/Delivery',
views: {
'view': {
templateUrl: 'Delivery.html',
},
},
})
.state('peopleOne', {
url: '/peopleOne',
parent: 'home',
views: {
'view#': {
templateUrl: 'peopleOne.html'
}
},
})
.state('peopleTwo', {
url: '/peopleTwo',
parent: 'home',
views: {
'view#': {
templateUrl: 'peopleTwo.html'
}
},
})
})
A few problems I've noticed:
First, put a console.log after the $stateProvider configuration calls to setup your routes. You will see that this code is never even called. Your angular app is not quite set up properly. You are using dat-ng-app in the index template, when you should be using ng-app. Otherwise angular is never actually used.
The next issue is in your $stateProvider configuration. I am not sure which documentation you are following, but your configurations for the states should look something like this:
# Set the default state
$urlRouterProvider.otherwise('/home')
# Configures home, peopleOne, and peopleTwo states
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'home.html'
})
.state('peopleOne', {
url: '/peopleOne',
templateUrl: 'peopleOne.html',
parent: 'home'
})
.state('peopleTwo', {
url: '/peopleTwo',
templateUrl: 'peopleTwo.html',
parent: 'home'
})
Finally, when actually creating the links in your template, I find it easier to use the ui-sref tag, which allows you to create a link based on a state name. So a link to the peopleOne state would look like this: <a ui-sref="peopleOne"></a>.
I've attached a plunker based off your original code
https://plnkr.co/edit/NazuoFoDOa3VGR6smoyH
I have a very basic angular ui router module set up for a website I am working on. It is as follows:
var myApp = angular.module('main', ['ui.router']);
myApp.config(function($stateProvider){
$stateProvider
.state('home', {
url: '/home',
templateUrl: './home_screen.htm'
})
.state('nowshowing1', {
url: '/nowshowing1',
templateUrl: './now_showing.htm'
})
.state('nowshowing2', {
url: '/nowshowing2',
templateUrl: './now_showing.htm'
})
.state('comingsoon1', {
url: '/comingsoon1',
templateUrl: './now_showing.htm'
})
.state('comingsoon2', {
url: '/comingsoon2',
templateUrl: './now_showing.htm'
})
.state('concessions', {
url: '/concessions',
templateUrl: './home_screen.htm'
})
.state('freemovies', {
url: '/freemovies',
templateUrl: './FreeMovies.htm'
})
.state('pictures', {
url: '/pictures',
templateUrl: './pictures.htm'
})
.state('contributors', {
url: '/contributors',
templateUrl: './contributors.htm'
})
.state('about', {
url: '/about',
templateUrl: './home_screen.htm'
});
});
I have a bootstrap carousel and my ui-view inside the carousel. Right now, my website works when using my bootstrap navbar to navigate to each page, where each page is an html page, but also a 'slide' in the carousel. I want the user to be able to use the arrow buttons on the side of the screen to switch to the next and previous 'slide' or page.
I am very new to angular and angular ui router, and I have not been able to find useful documentation on how I might not only access the current, next, and or previous states in my stateProvider, but how to call the method that will access those from my html.
I tried a controller like this:
myApp.controller('StateChangeCtrl', function($scope, $state){
$scope.previousState = function(){
console.log('Previous State!', $scope);
}
});
Then tried to call previousState() onclick of the arrow buttons in the carousel, but got a not defined error.
How/where would I access the current, next, and or previous state of the website if my pages go in the order of how I declared them in the stateProvider, and then how would I call the function from html that would do that?
If I could even access the current state somewhere, I can hardcode what the next and previous states will be (I assume I'd use $state.go() to change states) because I know the order of my html pages and there are not a ton of them...
I have this classic ionic view refresh problem:
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.state('app.menu', {
url: "/menu",
views: {
'menuContent': {
templateUrl: "templates/headmenu.html"
}
}
})
.state('app.menu.media', {
url: "/media/:MediaType",
views: {
'media-tab': {
templateUrl: "templates/tabs/media.html",
controller: "MediaCtrl"
}
}
}).state('app.settings', {
url: "/settings",
views: {
'settingsContent': {
templateUrl: "templates/settings.html",
controller: "SettingsCtrl"
}
}
})
The app start from 'app.menu.media' state, I click on 'settings', the view is loaded, but the problem occurs when I try going back to 'app.menu.media' state, the view is not refreshed (I still have the 'settings' view)
One of the solutions suggested by other devs is using ui-sref-opts="{reload: true, notify: true}" inside a <a ui-sref="app.menu.media" ...> ..</a> tag, but it's not smooth, the users feel like if the app freezes for a short time, and the same goes for the javascript solution: $state.go('app.menu.media', {}, {reload: true});
I know that the controller is not loaded when it is in the same state, but in this example we have different controllers: "MediaCtrl" and "SettingsCtrl", so why we have this problem? Is there any clean solution to fix this problem?
Edit:
This problem occurs even if I'm disabling the cache: $ionicConfigProvider.views.maxCache(0);
After Debuging the app, I found that the problem was not related to cache, but it doesn't mean that enabling the views cache will not affect the app, disabling the cache was important for my case.
So the problem was related to the fact that I was using the same state "app" for both 'media' and 'settings' views, with different view names: "settingsContent" for "app.settings" and "menuContent" for "app.menu". So I had to add these two Ion-nav-views to the template Url linked to the "app" state, which is "menu.html", juste like this:
<ion-nav-view name="menuContent"></ion-nav-view>
<ion-nav-view name="settingsContent"></ion-nav-view>
So when I go back to "app.menu.media" state, the view is indeed loaded, but the "settings" view is still there, and it is hiding my new requested view "media"!
So what I did to fix this issue is to use the same Ion View name:
.state('app.menu', {
url: "/menu",
views: {
'THESAMENAME': {
templateUrl: "templates/headmenu.html"
}
}...
....
.state('app.settings', {
url: "/settings",
views: {
'THESAMENAME': {
templateUrl: "templates/settings.html",
controller: "SettingsCtrl"
}
}
And inside menu.html, I deleted the two previous lines, and replaced theme with:
<ion-nav-view name="THESAMENAME"></ion-nav-view>
I hope this could help someone
I am trying to use ui-router on my project.
Core module:
var core = angular.module('muhamo.core', ['angular-loading-bar', 'anguFixedHeaderTable', 'ui.router']);
Tracking module:
var app = angular.module(TRACKING_MODULE_NAME, ['muhamo.core']);
app.config(Configure);
Configure.$inject = ['$stateProvider', '$urlRouterProvider'];
function Configure($stateProvider, $urlRouterProvider) {
$stateProvider.state('contacts', {
templateUrl: '/static/partials/employee/employee-edit',
controller: function () {
this.title = 'My Contacts';
},
controllerAs: 'contact'
});
$urlRouterProvider.otherwise("/contacts");
console.log($stateProvider);
}
and the html definition :
<div ui-view></div>
It works fine if i click to a ui-sref link. But on page load it does not load the default view "/contacts". Am I missing something here?
UPDATE
It works after adding missing "url" property. But now I've another problem, if I extend my implementation like that :
function Configure($stateProvider, $urlRouterProvider) {
$stateProvider.state('employees', {
abstract: true,
url: "/employees"
/* Various other settings common to both child states */
}).state('employees.list', {
url: "", // Note the empty URL
templateUrl: '/static/partials/employee/employee-list'
});
$urlRouterProvider.otherwise("/employees");
console.log($stateProvider);
}
also with more states, ui-view is not rendering.
There are two fishy things in your implementation. You out an empty url and your default route is abstract. Try my changes below.
function Configure($stateProvider, $urlRouterProvider) {
$stateProvider.state('employees', {
abstract: true,
url: "/employees"
/* Various other settings common to both child states */
}).state('employees.list', {
url: "/list", // Note the empty URL
templateUrl: '/static/partials/employee/employee-list'
});
$urlRouterProvider.otherwise("/employees/list");
console.log($stateProvider);
Cheers
Yes. You need to set the state.url to '/contacts'
$stateProvider.state('contacts', {
url: '/contacts',
templateUrl: '/static/partials/employee/employee-edit',
controller: function () {
this.title = 'My Contacts';
},
controllerAs: 'contact'
});
It seems you forgot to set the url parameter, e.g.:
$stateProvider.state('contacts', {
url: "/contacts",
...
}
I'm trying to use $urlRouterProvider to redirect me from a parent state to a child one, though the child one is a URL that accepts a parameter. (child url: /:page?pageId).
I am simply hoping to enter the application by entering from www.example.com/home, where the $urlRouterProvider should then take over the routing.
The code looks something like this:
$urlRouterProvider.when('/home', '/home/?pageId=1');
$stateProvider.state('home', {
url: '/home',
abstract: true,
templateUrl: 'home.tpl.html'
}).state('home.page', {
url: '/:page?pageId',
templateUrl: '...'
});
As you can see, I was hoping that by using the $urlRouterProvider I would be able to direct the location from the /home (parent state) to the parameterized child state /:page?pageId by forcing the url /?pageId=1. Instead, it just appends a trailing slash to /home/.
Here is a very dysfunctional plnkr of this madness: http://plnkr.co/edit/XZ4jkhqzQmykIgx0CvH2?p=preview
Thanks!
There is a working plunker
I am not sure why the above notation is not working (if intended to skip it or not), but with this adjustment it will work:
$stateProvider.state('home', {
url: '/home',
abstract: true,
templateUrl: 'home.html',
controller: 'controller',
}).state('home.child', {
url: '/:page?pageId',
templateUrl: 'childtemplate.html',
params : { // HERE we do define the defaults
pageId: {value: 1}, // these would serve as a starting value
}
});
So, what we are effectively doing here, is to declaring the default value out of url, but in the params: {} setting:
...
params : {
pageId: {value: 1},
}
Check it here