ui-router named views with route and url - angularjs

just a quick question. Can named views in the ui-router for angular have routes and an url? And if so, how can I activate them?
I searched through the wiki, but can't find any info on that.
What I want is a app with three different child routes so only one can be active at a time, but they're supposed to be in different views, so I can nicely animate between them with an accordion effect.
Any help there?
Thanks!
EDIT: Here's some code of my routing so far:
function routeConfig($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('home', {
url: '/',
//templateUrl: 'app/main/main.html',
//controller: 'MainController',
//controllerAs: 'main',
views: {
'' : {
templateUrl: 'app/main/main.html',
controller: 'MainController',
controllerAs: 'main'
},
'contact': {
templateUrl: 'app/contact/contact.html',
controller: 'ContactController',
controllerAs: 'contact'
},
'profile': {
templateUrl: 'app/profile/profile.html',
controller: 'ProfileController',
controllerAs: 'profile'
},
'works': {
templateUrl: 'app/works/works.html',
controller: 'WorksController',
controllerAs: 'works'
}
}
});
$urlRouterProvider.otherwise('/');
$locationProvider.html5Mode(true);
}

I'd recommend just creating different states for each view. There's no reason you can't animate smoothly between different states.
So:
function routeConfig($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/main/main.html',
controller: 'MainController',
controllerAs: 'main'
})
.state('home.contact', {
templateUrl: 'app/contact/contact.html',
controller: 'ContactController',
controllerAs: 'contact'
})
.state('home.profile', {
templateUrl: 'app/profile/profile.html',
controller: 'ProfileController',
controllerAs: 'profile'
params: {
"user" : {}
}
})
.state('home.works', {
templateUrl: 'app/works/works.html',
controller: 'WorksController',
controllerAs: 'works'
})
}
});
$urlRouterProvider.otherwise('/');
$locationProvider.html5Mode(true);
}
In your ui-sref links, you can pass data to those views using parameters, like this: <a ui-sref="home.profile({user: contact.user}) along with the 'params' section in the state definition as I've included above.

Routing is serverside so if you call any address your serverside routing needs to launch proper html or javascripts which will let you render what you want.
For more accurate answer please respond with more details: what is your serverside engine, which version of angular you use etc.

Related

AngularJS ui-route $state, $scope and controller event loading

I'm kinda new with this UI-Route I know it's very powerful but i'm having problem working on it, I have use AngularJS before but not that often and this time i really want to use it so given that my questions goes like this (I've search everywhere regarding this but no luck for me):
The scenario is I have Index.html on that page I have two views
which are "News" and "Testi" both are confined on a div
So knowing that I added App.js (which will contain the initial code for my AngularJS implementation):
var app = angular.module('wrcheese', ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/Views/Index.html',
views: {
'main': {
templateUrl: '/Views/App/home.html'
},
'testi': {
templateUrl: '/Views/App/testimonial.html'
}
},
controller: 'HomeCtrl'
})
});
and my controller goes like this (homeController.js)
'use strict';
app.controller('HomeCtrl', function ($scope, $state) {
$scope.welcomeMessage = 'Welcome to WeRCheese';
});
my problem is that I'm trying to access that "welcomeMessage" on my home.html page but wasn't able to, what strange is that when i put in a breakpoint on my controller it wasn't hit it seems the controller does not exist.
Maybe I'm doing it wrong because I don't have any problem when i use ngRoute before.
Lastly, how do you add in a factory?
app.controller('HomeCtrl', function ($scope, $state, homeFactory) {
});
or
app.controller('HomeCtrl', ['$scope', '$state', 'homeFactory', function ($scope, $state, homeFactory) { }]);
TIA.
I was having problem adding a comment my mistake for not realizing that I need to edit my question here. Anyway for my problem I was able to load the controller via different page but I'm still having problem loading the controller on the Index.html i tried updating the .state -> tried on different approach i.e. use '', '/', 'index' in the views.
.state('home', {
url: '', or '/', or 'index',
templateUrl: '/Views/Index.html',
controller: 'HomeCtrl'
But still the controller is not loading, to be specific I have tried adding this line on my Index.html {{ welcomeMessage }} just to verify that the controller was/has been loaded properly.
When you have add views property to a state, the original template, templateUrl properties will be ignored, so you have to bind controllers in views.
$stateProvider.state('home', {
url: '/home',
templateUrl: 'Views/Index.html', <----- will be ignored
views: {
'main': {
templateUrl: 'Views/App/home.html',
controller: 'HomeCtrl'
},
'testi': {
templateUrl: 'Views/App/testimonial.html',
controller: 'HomeCtrl'
}
},
controller: 'HomeCtrl' <----- will be ignored
})
For factory: after defined it, you can inject it by both the ways you posted.
refer this plunker.
var app = angular.module('wrcheese', ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
views: {
'main': {
templateUrl: '/Views/App/home.html',
controller : 'HomeCtrl'
},
'testi': {
templateUrl: '/Views/App/testimonial.html',
controller : 'HomeCtrl'
}
},
})
});
you can do this
.state('home', {
url: '/home',
views: {
'#': {
templateUrl: '/Views/Index.html',
controller: 'HomeCtrl',
controllerAs: 'vm'
},
'main#home': {
templateUrl: '/Views/App/home.html'
},
'testi#home': {
templateUrl: '/Views/App/testimonial.html'
}
}
});
using controllerAs is a best practice

Ionic controllers alias not working when using sidebar

I have an app built using ionic framework, I follow the instructions on ionicframework learn page and now I am using the native sidemenu. The problem is, I can't use controller alias. Here is a snipet of my app.js with the route config:
angular.module('checklist-atendimento', [
'ionic',
'oc.lazyLoad',
'ngStorage',
'ngCordova',
'ngMask'
])
.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
$urlRouterProvider.otherwise('/app/atendimento/1');
$httpProvider.interceptors.push('TratamentoDeErrosService');
$stateProvider
.state('app', {
abstract: true,
url: '/app',
views: {
'conteudo': {
templateUrl: 'app/templates/menu.html'
}
}
})
.state('app.inicio', {
url: '/inicio',
views: {
'menuContent': {
templateUrl: 'app/views/inicio.html',
controller: 'InicioController',
}
}
})
.state('app.atendimento', {
url: '/atendimento/:codMenu',
views: {
'menuContent': {
templateUrl: 'app/views/atendimento.html',
controller: 'AtendimentoController',
controllerAs: 'atendimentoCrl'
}
}
})
});
As you can see, I have 2 states, one without controllerAs (InicioController) and the other using controllerAs (AtendimentoController).
In controller I put
$scope.test ="TEST!!!"
and in the view I put
<b>{{atendimentoCtrl.test}}<b>
Nothing happens, if I use just {{test}}, but the text is shown.
Anyone knows how to do it ?
EDIT:
HERE there is a example of what a talking about:
http://plnkr.co/ohL5HE
Look inside ItemCtrl and inside index.html, on item.html.
I tried use an alias to controller but it don't works.
You need to change
$scope.test ="TEST!!!"
to:
this.test ="TEST!!!"
The issue here is just a typo... This is a controller state
.state('app.atendimento', {
url: '/atendimento/:codMenu',
views: {
'menuContent': {
templateUrl: 'app/views/atendimento.html',
controller: 'AtendimentoController',
controllerAs: 'atendimentoCrl'
}
}
})
where we can see 'atendimentoCrl'. And here is a view statement
<b>{{atendimentoCtrl.test}}<b>
where we can see atendimentoCtrl (compare Ctrl suffix and Crl above)
So, there is missing t in the controllerAs

Configure UI-Router for Multiple Modules

I'm making a project in Angular 1.4, and i'm using ui-router, I have split my project in several sub-modules, there's one 'parent' module (not sure if i'm using the concept of parent and child right) and several 'child' modules.
The 'parent' has routes for the global login, and the two main menus of each group, the groups are: guides, projects; each one of them has it's own 'child' modules some of them are: guides[Web, Mobile, Desktop], projects[Business, Community]. Each module has it's own routes, and what i want is to be able to route the app though each module.
The main routes are:
/
/login
/guides
/guides/login
/guides/web
/guides/mobile
/guides/desktop
/projects
/projects/login
/projects/business
/projects/community
The site has somehow same login concept of SE, people can have a global account, or a single account on a specific module.
What i've tried so far if to make the routes as Doc says:
angular.module('main', ['main.guides', 'main.projects']).config(function ($stateProvider) {
$stateProvider.
state('main', {
url: '/',
templateUrl: './views/index.html',
controller: 'IndexCtrl'
}).
state('login', {
url: '/login',
templateUrl: './views/login.html',
controller: 'LoginCtrl'
}).
state('guides', {
url: '/guides',
templateUrl: './views/guides-menu.html',
controller: 'GuidesCtrl'
}).
state('projects', {
url: '/projects',
templateUrl: './views/projects-menu.html',
controller: 'ProjectsCtrl'
});
});
angular.module('main.guides', []).config(function ($stateProvider) {
$stateProvider.
state('main.guides-login', {
url: '/login',
templateUrl: './views/login.html',
controller: 'LoginCtrl'
}).
state('main.guides-menu', {
url: '/login',
templateUrl: './views/menu.html',
controller: 'LoginCtrl'
}).
state('main.guides-web', {
url: '/web',
templateUrl: './views/web/list.html',
controller: 'ListCtrl'
}).
state('main.guides-mobile', {
url: '/web',
templateUrl: './views/mobile/list.html',
controller: 'ListCtrl'
});
});
angular.module('main.projects', []).config(function ($stateProvider) {
$stateProvider.
state('main.projects-login', {
url: '/login',
templateUrl: './views/login.html',
controller: 'LoginCtrl'
}).
state('main.projects-business', {
url: '/business',
templateUrl: './views/business/list.html',
controller: 'ListCtrl'
}).
state('main.projects-menu', {
url: '/business',
templateUrl: './views/menu.html',
controller: 'ListCtrl'
}).
state('main.projects-community', {
url: '/business',
templateUrl: './views/community/list.html',
controller: 'ListCtrl'
})
});
But don't know how to access to those urls... also would like some opinion about this approach, would there be a better practice?
I created a plunkr to demo your states. I altered the code to use templates instead of templateUrl but that shouldn't change what you are trying to figure out. I made some assumptions about your layout based on the urls provided. If you pop it out into the external viewer you can see the urls being used. Find it here:
http://plnkr.co/edit/9lPQ3GlmH0AEqhzX7lj9?p=preview
Urls in the ui-router are used as part of what specifies the state. So when you want /projects/business you have a state that is a child of projects that has a url of /business. Something like:
state('projects.business', {
url: '/business',
template: '<div> projects business</div>',
controller: 'ListCtrl'
})
The dot notation in the state definition tells the ui router that this is child state of projects. The url value provided is added to the parent state url.
I think your module strategy is solid. You just need to wrap your head about the parent child relationships used in the ui.router.

Nested sates and views in Angular UI Route

Sorry if similar questions have been asked before but I have been strugling to get a certain setup working for a while. I took a working plunker from from an existing question and am trying to tweak it just a little to my needs.
Orginal Plunker: http://plnkr.co/edit/uY1Sl3f0KCTukPGHDRdW
My (slightly) edited fork: http://plnkr.co/edit/hlw4Et00UeGjzxD4Mszi
What I am trying to achieve is a base layout containing a header, footer and unnamed view for the page content. I can do this fine with the original plunker. But when I try to get more fancy and have a structure more like this:
$urlRouterProvider.otherwise('/home/list');
$stateProvider
.state('root', {
abstract: true,
views: {
'#': {
controller: 'RootCtrl',
controllerAs: 'rootCtrl'
},
'header#': {
templateUrl: 'header.html',
controller: 'HeaderCtrl',
controllerAs: 'headerCtrl'
},
'footer#': {
templateUrl: 'footer.html',
controller: 'FooterCtrl',
controllerAs: 'footerCtrl'
}
}
})
And here is the adjusted state definition:
.state('root.home', {
parent: 'root',
url: '/home',
views: {
'#': {
template: '<ui-view></ui-view>',
controller: 'HomeController',
controllerAs: 'homeCtrl'
},
'list#root.home': {
url: '/list',
template: 'homeList.html',
controller: 'HomeController',
controllerAs: 'homeCtrl'
}
},
});
What I am trying to do here is make it so that 'root.home' state is just a base state for prepending the URL 'home' or whatever the url is in my real application. I have tried ready though the ui-route sample app but it's a lot to take in and am going in circles. I'm sure this is simple...
There is a working updated plunker. There is one state definition adjustment.
This was original piece of code:
.state('root.home', {
parent: 'root',
url: '/home',
views: {
'#': {
template: '<ui-view></ui-view>',
controller: 'HomeController',
controllerAs: 'homeCtrl'
},
'list#root.home': {
url: '/list',
template: 'homeList.html',
controller: 'HomeController',
controllerAs: 'homeCtrl'
}
},
});
What was wrong there? Firstly a note - we do not need to define parent: 'root', because our parent is in our name 'root.home'. So, to make it more clear, I decided to keep parent setting, while change the state name into 'home'.
Secondly, we have two views in play for our state, but the second one, is ordered to be injected into the first one.
// this line is instructing UI-Router: inject this into
// the other view definition of the current state
// search for ui-view="list"
'list#root.home'
but there was no ui-view="list" defined.
Finally, we cannot declare url for views. Url belongs just to states:
// this is wrong. The view cannot have url
// url is for state
'list#root.home': {
url: '/list',
So, we should introduce the child of our state... 'home.list'
This is the adjusted state(s) definition (from the new working plunker):
.state('home', {
parent: 'root',
url: '/home',
views: {
'#': {
template: '<div ui-view="list"></div>',
controller: 'HomeController',
controllerAs: 'homeCtrl'
}
},
})
.state('home.list', {
url: '/list',
views: {
'list': {
templateUrl: 'homeList.html',
controller: 'HomeController',
controllerAs: 'homeCtrl'
}
},
});

Angular routing for different layouts

How do I load different layouts ?
Currently I have three layouts for my backend, one for admin, one for user and last for teacher i.e adminLayout.html, userlayout.html and teacherLayout.html for dashboards.
I am writing my routes something like this -
app.config(function($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'views/pages/home.html',
controller: 'homeCtrl'
})
.when('/users/login', {
templateUrl: 'views/users/login.html',
controller: 'usersLoginCtrl'
})
.when('/users/dashboard', {
templateUrl: 'views/users/dashboard.html',
controller: 'usersDashCtrl'
})
.when('/teachers/login', {
templateUrl: 'views/teachers/login.html',
controller: 'teachersLoginCtrl'
})
.when('/teachers/dashboard', {
templateUrl: 'views/teachers/dashboard.html',
controller: 'teachersDashCtrl'
})
});
For /users/dashboard I want usersLayout.html and /teachers/dashboard I want teachersLayout.html.
How could I acheive this ?
I tried $window.location.href = "LINK_TO_LAYOUT"; but its is taking the whole path in the URL, however I want to my URL like -
mysite.com/teachers/dashboard
mysite.com/users/dashboard
mysite.com/admin/dashboard
You should use Ui-Router.
It support nested views.
So in your example your routes would be like this.
app.config(function($stateProvider){
$stateProvider
.state('main', {
url: '/',
templateUrl: 'views/pages/home.html',
controller: 'homeCtrl'
})
.state('users', {
url: '/users',
templateUrl: 'views/users/layout.html'
})
.state('users.login', {
url: '/users/login',
templateUrl: 'views/users/login.html',
controller: 'usersLoginCtrl'
})
.state('users.dashboard', {
url: '/users/dashboard',
templateUrl: 'views/users/dashboard.html',
controller: 'usersDashCtrl'
})
.state('teachers', {
url: '/teachers',
templateUrl: 'views/teachers/layout.html'
})
.state('teachers.login', {
url: '/teachers/login',
templateUrl: 'views/teachers/login.html',
controller: 'teachersLoginCtrl'
})
.state('teachers.dashboard', {
url: '/teachers/dashboard',
templateUrl: 'views/teachers/dashboard.html',
controller: 'teachersDashCtrl'
})
});
Then you need to creat this new Layout Pages.
On: views/users/layout.html
<div id="usersLayout">
<ui-view/>
</div>
On: views/teachers/layout.html
<div id="teachersLayout">
<ui-view/>
</div>
Hope this get you going.
One of ways use 'abstract' state from ui-router
$stateProvider
.state('contacts', {
abstract: true, // <<< this is your layout
url: '/contacts',
// Note: abstract still needs a ui-view for its children to populate.
// You can simply add it inline here.
// >>> Or use templateUrl: 'contactLayout.html'
template: '<ui-view/>'
})
.state('contacts.list', {
// url will become '/contacts/list'
url: '/list'
//...more
})
.state('contacts.detail', {
// url will become '/contacts/detail'
url: '/detail',
//...more
})
Please spend some time for learning ui-router and you will have powerfull and simple tool for routing in angularjs.
Check docs for more info about abstract state.

Resources