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.
Related
Here is my $stateProvider configuration:
.state('itemDetail', {
abstract: true,
url: '/itemDetail/general/:itemid',
controller: 'ItemDetailsController',
templateUrl: './partials/itemDetails.html'
})
.state('itemDetail.general', {
url: "",
controller: 'ItemDetailsController',
templateUrl: "./partials/itemDetails.General.html"
})
.state('itemDetail.file', {
url: "/file/:itemid",
controller: 'ItemDetailsController',
templateUrl: "./partials/itemDetails.File.html"
})
The user can look at item using #/itemDetail/general/96045 and can click the link to look at file attachments. Now it is work but URL for files now is #/itemDetail/general/96045/file/96045.
Is it possible to have URL for files as #/itemDetail/file/96045?
Well, I would go with one parent and only one child state. There is a working plunker
This will be the new one child state itemDetail.type:
.state('itemDetail', {
abstract: true,
url: '/itemDetail',
controller: 'ItemDetailsController',
templateUrl: 'partials/itemDetails.html'
})
.state('itemDetail.type', {
url: "/:type/:itemid",
controller: 'ItemDetailsController',
templateProvider: ['$stateParams', '$templateRequest',
function($stateParams, $templateRequest) {
var url = "partials/itemDetails.General.html";
if($stateParams.type === "file"){
url = "partials/itemDetails.File.html"
}
return $templateRequest(url);
}],
})
We are using here $stateParams.type to decide which template to load (and also $templateRequest to profit from angula built in caching)
And this will be the calling html:
<a ui-sref="itemDetail.type({type:'general', itemid:1})">
<a ui-sref="itemDetail.type({type:'file', itemid:22})">
The url will now look as expected
check it here
Yes it can be you need to give state as
.state('itemDetail.file', {
url: '/{itemId}',
controller: 'ItemDetailsController',
templateUrl: 'partials/itemDetails.html'
})
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.
i make an mobile site for buy/renew/transfer/ domains.
The whole app has 4 templates connected into functional chain.
Buy : Search -> (login if needed?) -> Pay -> -Confirmation
Renew : Choose -> (login if needed?) -> Pay -> -Confirmation
Transfer: Choose -> (login if needed?) -> Pay -> -Confirmation
While the app has the same templates, the functionality and titles are different. And i want to be able to check the parent state within every state in order to make dynamic changes, and switch request strings.
The simplest way is to define 12 (4X3) routes in my stateProvider. but i'm looking for more effective way to do this by unite buy.search, renew.search, transfer.search and others in three groups of routes. is it possible? Do any one may suggest me other approach?
Thanks
===UPDATE===
current stateProvider
.state('app.buy.search', {
url: "/search",
templateUrl: "templates/search_domain.html",
controller: 'SearchCtrl'})
.state('app.buy.login', {
url: "/buy/login",
templateUrl: "templates/login.html",
controller: 'LoginCtrl'})
.state('app.buy.pay', {
url: "/buy/pay",
templateUrl: "templates/pay.html",
controller: 'PayCtrl'})
.state('app.renew.search', {
url: "/search",
templateUrl: "templates/search_domain.html",
controller: 'SearchCtrl'})
.state('app.renew.login', {
url: "/buy/login",
templateUrl: "templates/login.html",
controller: 'LoginCtrl'})
.state('app.renew.pay', {
url: "/buy/pay",
templateUrl: "templates/pay.html",
controller: 'PayCtrl'})
.state('app.transfer.search', {
url: "/search",
templateUrl: "templates/search_domain.html",
controller: 'SearchCtrl'})
.state('app.transfer.login', {
url: "/buy/login",
templateUrl: "templates/login.html",
controller: 'LoginCtrl'})
.state('app.transfer.pay', {
url: "/buy/pay",
templateUrl: "templates/pay.html",
controller: 'PayCtrl'})
You can reduce the router configurations by applying dynamic url. In your case, pages (search, pay, login) are same for modules (buy, renew, transfer). So you can change the configuration as follows
$stateProvider
.state('app', {
url: '/',
templateUrl: 'dashboard.html',
controller: 'MainCtrl'
})
.state('app.search', {
url: '{module}/search',
views: {
"searchView": {
templateUrl: 'search.html',
controller: 'SearchCtrl'
}
}
})
.state('app.pay', {
url: '{module}/pay',
views: {
"payView": {
templateUrl: 'pay.html',
controller: 'PayCtrl'
}
}
})
.state('app.login', {
url: '{module}/login',
views: {
"loginView": {
templateUrl: 'login.html',
controller: 'LoginCtrl'
}
}
})
Demo: http://plnkr.co/edit/NGsZJB?p=preview
Hello when i have this states defined:
.state('locations', {
url: '/locations',
templateUrl: '/templates/locations/index.html',
controller: 'LocationsCtrl'
})
.state('locations.show', {
url: '/{location_id}',
templateUrl: '/templates/locations/show.html'
});
How can i have /templates/locations/index.html to show for example a list of all locations,
but templates/locations/show.html to show a view of the location, but not nested inside the view of index.html. Basically i want the routes nested, but not the views.
I just worked on an example similar to yours
.state('overview', {
url: '/all',
templateUrl: '_/partial/overview/all.html',
controller: 'homeCtrl'
})
.state('places', {
url: '/:id/place',
templateUrl: '_/partial/details/detail-place.html',
controller: function($scope, $stateParams) {
$scope.path = $scope.paths[$stateParams.id];
}
})
In your case
.state('locations', {
url: '/locations',
templateUrl: '/templates/locations/index.html',
controller: 'LocationsCtrl'
})
.state('show', {
url: '/{location_id}',
templateUrl: '/templates/locations/show.html'
});
That means the show state shouldn't be nested under locations.
I have a wizard based process for creating quotes. I'm using angularjs ui-router to manage the wizard urls. The routes shown below work fantastic for creating a new quote. I now need to go back in to edit existing quotes and need to figure out how to use the ID in the URL. I was thinking something like baseUrl/quote#/3/options (quote #3 options step). Currently the url looks like baseUrl/quote#/options. If I change the url in the .state definition from url: 'options', to url:':quoteId/options' it breaks my routes (can no longer get to the option step). Also this wouldn't work for a new quote since it doesn't yet have an ID. What's the best way to get this to work?
quoteWizardModule.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('wizard', {
url: '',
templateUrl: 'Scripts/templates/quoteWizard/wizardLayout.html',
controller: 'wizardNavigationCtrl'
})
.state('wizard.options', {
url: 'options',
templateUrl: 'Scripts/templates/quoteWizard/wizardOptions.html',
controller: 'wizardOptionsCtrl'
})
.state('wizard.newmodel', {
url: 'newmodel',
templateUrl: 'Scripts/templates/quoteWizard/wizardModel.html',
controller: 'wizardModelCtrl',
})
.state('wizard.model', {
url: 'model/:factoryId/:index',
templateUrl: 'Scripts/templates/quoteWizard/wizardModel.html',
controller: 'wizardModelCtrl'
})
.state('wizard.other', {
url: 'other',
templateUrl: 'Scripts/templates/quoteWizard/wizardOther.html',
controller: 'wizardOtherCtrl'
})
.state('wizard.customer', {
url: 'customer',
templateUrl: 'Scripts/templates/quoteWizard/wizardCustomer.html',
controller: 'wizardCustomerCtrl'
})
.state('wizard.shipping', {
url: 'shipping',
templateUrl: 'Scripts/templates/quoteWizard/wizardShipping.html',
controller: 'wizardShippingCtrl'
})
.state('wizard.notes', {
url: 'notes',
templateUrl: 'Scripts/templates/quoteWizard/wizardNotes.html',
controller: 'wizardNotesCtrl'
})
.state('wizard.review', {
url: 'review',
templateUrl: 'Scripts/templates/quoteWizard/wizardReview.html',
controller: 'wizardReviewCtrl'
});
}]);