I have 2 states in my app currently. Each app has multiple views. I want on state to be activated on app start up. Right now, when the app starts, I only get the links. Then I have to click on any link to activate any state. How do I make a state opened by default?
states conf
var app = angular.module('dategenie', ['ui.router', 'ui.bootstrap', 'geolocation', 'ngIdle', 'infinite-scroll']);
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to /profile
$urlRouterProvider.otherwise('/');
// Now set up the states
$stateProvider.state('profile', {
views: {
mainModule: {
url : '/profile'
, templateUrl : 'partials/profile.html'
, controller: 'ProfileCtrl'
}
, rightPaneModule: {
templateUrl: 'partials/location.html'
, controller: 'LocationCtrl'
}
}
})
.state('profiles', {
views: {
mainModule: {
url : '/'
, templateUrl : 'partials/home.html'
, controller : 'HomeCtrl'
}
, chatModule: {
templateUrl : 'partials/chat.html'
, controller: 'ChatCtrl'
}
}
});
}]);
HTML
a(ui-sref="profile") Profile
a(ui-sref="profiles") Home
a(href="/logout") Logout
div(ui-view="mainModule")
div(ui-view="chatModule")
div(ui-view="rightPaneModule")
Thanks!
First of all, your url declaration should be outside of the views object.
So this is how your profiles state would look like:
.state('profiles', {
url : '/',
views: {
mainModule: {
templateUrl : 'partials/home.html'
, controller : 'HomeCtrl'
},
chatModule: {
templateUrl : 'partials/chat.html'
, controller: 'ChatCtrl'
}
}
});
Note: I'm not sure if this is still a valid concern, but I would put all of my view names in quotes. If memory serves me right, this had some implications earlier on with UI-router - not sure if that still applies.
Secondly, you need to make sure you have HTML5 Pushstate enabled if you wish for routing to pick up an active state on "/". Otherwise your 'root' would be "/#/".
Here's some code you can slap in say a push-state.js file;
app.config(['$locationProvider', function($locationProvider) {
return $locationProvider.html5Mode(true);
}]);
Quite useful to have in it's own file when you stumble upon errors with client side routing, I find most of my issues arise from PushState indescrepencies (so toggling it on and off is a nice little advantage when debugging).
Hope that works out for you, good luck : )
Related
I am currently working on a web development project and I am having a problem in implementing UI-router (AngularJS).
I want to set a default state when the page loads and also default state for the child view.
If I use abstract:true method that is not the solution because when I want to again active that state it won't be possible.
Hope this will give you answer to your Question
var App = angular.module('TechdefeatApp',['ui.router']);
App.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider){
// For any unmatched url, send to /business
$urlRouterProvider.otherwise("/")
$stateProvider
.state('/', {
url: "/",
templateUrl: "app/components/home/homeView.html",
controller:"homeController"
})
.state('member', {
url: "/member/:seo_url",
templateUrl: "app/components/member/memberView.html",
controller:"memberController"
})
.state('category', {
url: "/category/:seo_url",
templateUrl: "app/components/category/categoryView.html",
controller:"categoryController"
})
}]);
you need to use at $urlRouterProvider service,
first inject this service, after that write
$urlRouterProvider.otherwise('/otherwise').
Pay attention that the /otherwise url must be defined on a state as usual:
$stateProvider
.state("otherwise", { url : '/otherwise'...})
good luck!
I am trying to create a link in my template angularjs by doing something like:
<a ng-href="/#!/content/[[value.id]]">[[key]]</a>
But I am wondering myself if is possible do something like symfony2 does, example:
routing.yml
home_redirect:
path: /
defaults:
_controller: FrontendBundle:Controller:function
path: /home
permanent: true
options:
expose: true
And using it in your twig template by doing:
one link to home
That is really, really helpful because I don't have to "hardcode" all my routes.
To ensure a proper routing, you can use ui-router.
Here is an exemple on plunker
How this works :
1 - Follow the installation guide on their github
2 - Write your state definition :
app.config(function($stateProvider, $urlRouterProvider){
//If no route match, you'll go to /index
$urlRouterProvider.otherwise('/index');
//my index state
$stateProvider
.state('index', {
url: '/index',
templateUrl: 'index2.html',
controller: 'IndexCtrl'
})
//the variable state depending on an url element
.state('hello', {
//you will be able to get name with $stateParams.name
url: '/hello/:name',
templateUrl: 'hello.html',
controller: 'HelloCtrl'
})
});
3 - Write links by their state name :
//add this directive to an html element
//This will go to /index
ui-sref="index"
//This will go to /hello/
ui-sref="hello"
//This will go to /hello/ben
ui-sref="hello({name:'ben'})"
//This will go to /hello/{myname}
ui-sref="hello({name:myname})"
4 - Get the param into your controller :
//inject $stateParams
app.controller('HelloCtrl', function($scope, $stateParams){
$scope.controller = "IndexCtrl";
//get the param name like this
$scope.name = $stateParams.name;
});
Hope it helped. Also keep in mind the ui-router got some really powerful tools such as resolve and nested state/view. You'll probably need theses now or later.
PS : If the plunker don't work, just fork it and save again.
You could do this :
'use strict';
angular.module('AngularModule')
.config(function ($stateProvider) {
$stateProvider
.state('YourStateName', {
url: '/your/url',
views: {
'aViewName': {
templateUrl:'views/components/templates/yourTemplate.html',
controller: 'YourController'
}
},
resolve: {
}
});
});
// then in your controller
angular.module('AngularModule')
.controller('MyController',function($scope, $state){
$scope.goTo = function(){
$state.go('YourStateName');
}
}
);
//in your html make sure the <a> tag is in scope with the 'MyController'
<a ng-click='goTo'>[[key]]</a>
or
you can just do this :
<a ng-href="/your/url"></a>
that way you bypass the controller you can still put logic in the controller that was specified in the state
I'm working on a AngularJS + OnsenUI project, and I'm having problems with the navigation.
Let's say that I have a module:
angular
.module('app.home', ['ui.utils','ngRoute','ngAnimate'])
.controller('HomeCtrl', HomeCtrl)
.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'path/to/home/template',
controller: 'HomeCtrl'
})
.when('/test1', {
templateUrl: 'path/to/template',
controller: 'TestOneCtrl'
})
.when('/test2', {
templateUrl: 'path/to/template',
controller: 'TestTwoCtrl'
})
.otherwise({
redirectTo: 'path/to/home/template'
});
});
In the HomeCtrl I'm supposed to (depending on the result of certain functions) navigate to either test1.html or test2.html. My problem is that I don't know how to link the routeProvider to the the ons.navigator.pushPage function.
This doesn't work:
var url = '/test1';
$scope.navigator.pushPage( url, { animation : 'slide' } );
This works:
var url = '/absolute/path/to/template';
$scope.navigator.pushPage( url, { animation : 'slide' } );
My question is what do I need to do so I don't have to write the absolute path to the template in the url variable? Apparently I'm missing out on something, but I can't figure out what.
Thanks in advance!
I think it's because the path used in $routeProvider is not the same type of that of pageUrl used in navigator.pushPage().
$routeProvider.when(path, route);
and
navigator.pushPage(pageUrl, option);
Path is like the pattern or string of your app url found in the browser address bar. For example, "http://localhost:8000/app/index.html#/test1". That's when you can refer to this in the routeProvider as "/test1". However, in the navigator.pushPage(), you will need to specify exact url to the page just like how you set ur templateUrl inside $routeProvider. In other words, pageUrl = route.
That's just from my understanding though.
I am building the front-end app for a REST service, and most of the resources are located at long urls where most of the segments are dynamic based on records created in the app by users. Obviously I won't be able to know or create hardcoded routes for most of these records.
My question I suppose is how to handle urls like this with ui-router:
<semester>/<program>/<class>/enrollment
or
<semester>/myclasses/<class>/assignments
There is always at least one static, predictable segment in every resource url, and the segments are always in a predictable order.
Do I make abstract states for each segment in the url like:
$stateProvider.state(semester)
.state(program)
.state(class)
.state(assignments);
??
I've tried building routes that look like this:
param = {
name: "param",
url: "/:hue/:temp/param",
templateUrl: "http://localhost:81/route/tpl/param.tpl.html",
controller: "paramController"
};
but it ends up sending me back to the .otherwise() state when I link to the "param" state.
Thanks for any help, I'm a bit stumped.
I had a similar problem and I quickly coded this:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state('app', {
url : "/app",
abstract : true,
templateUrl : "layout/navigation-drawer.tpl.html"
}).state('app.help', {
url : "/help",
views : {
'menuContent' : {
templateUrl : "layout/help.html"
}
}
}).state('app.settings', {
url : "/settings",
views : {
'menuContent' : {
templateUrl : "layout/settings.html"
}
}
}).state('app.rate-us', {
url : "/rate-us",
views : {
'menuContent' : {
templateUrl : "layout/rate-us.html"
}
}
}).state('app.projects', {
url : "/projects",
views : {
'menuContent' : {
templateUrl : "layout/projects.html",
controller : 'ProjectsCtrl'
}
}
}).state('app.forms', {
url : "/:project_name/forms",
views : {
'menuContent' : {
templateUrl : "layout/forms.html",
controller : 'FormsCtrl'
}
}
}).state('app.entries', {
url : "/:project_name/:form_name/entries/:form_id",
views : {
'menuContent' : {
templateUrl : "layout/entries.html",
controller : 'EntriesCtrl'
}
}
});
which is working, "/:project_name/:form_name/entries/:form_id" will resolve to something like app/Mirko_test/University/entries/1
Ok so I tested this out and it works in my case. It fails when the state is only a parameter, but it seems as long as each state has a non-parameterized bit, ui-router is able to parse down to children states. I haven't seen this case demonstrated or explained anywhere before. Most tutorials only cover simple hardcoded nested states and not parameterized ones.
It's not ideal, but it works.
I hope this helps someone else facing this issue. :)
var app = angular.module('app', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ( $stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise("/");
$locationProvider.html5Mode(true);
var semester = {
name: "semester",
abstract: true,
url: "semester/:sem",
templateUrl: "http://localhost:81/route/to/semtemplate.tpl.html",
controller: "semesterController"
},
program = {
name: "program",
parent: sem,
url: "program/:prg",
templateUrl: "http://localhost:81/route/to/prgtemplate.tpl.html",
controller: "programController"
},
classes = {
name: "classes",
parent: prg,
url: "/classes",
templateUrl: "http://localhost:81/route/to/clstemplate.tpl.html",
controller: "classesController"
};
$stateProvider.state(sem)
.state(prg)
.state(classes);
}]);
app.controller('paraController', ['$scope', '$stateParams', '$state',function($scope, $state, $stateParams){
console.log('paraController instantiated');
$scope.sem = $stateParams.params.sem;
$scope.prg = $stateParams.params.prg;
}]);
As this is a hierarchical REST api this pattern works perfectly, and when also taking advantage of scope inheritance from each controller it should be a good fit for my project. I haven't tested extremes of nested states, but it would be interesting to see how it behaves under even more parameterized states. The only limitation I have found is that each state needs to have a non-parameterized part as well. So /:sem fails but semester/:sem works fine.
It's not ideal as it makes URLs longer, but I haven't found a workable alternative.
I know this question is old, but I had essentially the same question recently and found the official answer. Apparently, angular ui-router now supports the notion of URL Parameters in URL Routing, which allow you to specify parameters, along the lines of the following:
$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});
}
})
For more info, go here: https://github.com/angular-ui/ui-router/wiki/URL-Routing#url-parameters
I'm implementing AngularUI's routing and appear to be missing something about how to configure a default URL. It seems like the below code would default the user to /dashboard/tree but if I refresh the page, the url appends another /dashboard, so I end up with /dashboard/dashboard/dashboard/dashboard/tree.
How can I properly set the default URL without having this appending issue when the user first visits the page?
config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/dashboard/tree');
/* URL mappings */
$stateProvider.
state('dashboard', {
url: '/dashboard',
views: {
'page': {
templateUrl: '/partials/admin/dashboard.htm'
}
}
}).
state('dashboard.tree', {
url: '/tree',
views: {
'content': {
templateUrl: '/partials/admin/tree-overview.htm'
}
}
});
}])
Believe it or not, this is probably a bug/feature in angular 1.1.5 (reloads add stuff to the url).
Try setting this in your head:
<base href="/"></base>