Related to Angular Routes(single page application) - angularjs

Would like someone to help me in front end UI routing using angularjs?
Am designing login & register setup but routing is not working perfectly and also bootstrap rendering does not render it properly when connected via MVC structure..
.

You can use UI-ROUTER for routing in angular js.
UI-Router applications are modelled as a hierarchical tree of states. UI-Router provides a state machine to manage the transitions between those application states in a transaction-like manner.
Here is an example route configuration,
$stateProvider
.state('register', {
url: '/register',
templateUrl: 'register.html',
controller: 'registerController'
})
.state('login', {
url: '/logn',
templateUrl: 'login.html',
controller: 'loginController'
})
.state('home', {
url: '/home',
templateUrl: 'partial-home.html'
})
// nested list with custom controller
.state('home.list', {
url: '/list',
templateUrl: 'partial-home-list.html',
controller: function($scope) {
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
// nested list with just some random string data
.state('home.paragraph', {
url: '/paragraph',
template: 'I could sure use a drink right now.'
})
Github link for documentation
Another reference for ui-router
A Demo for routing and navigation using ui-router

Related

Angular UI Router - Dynamic TemplateURL

I am building a static HTML website with angular UI router for navigation. I basically have one ui-view with multiple (10+) html templates (pages) to load into that view. All my template pages are in a directory called 'pages'.
So i basically want to know if we can define just one state in the $stateProvider to assign multiple template urls dynamically instead of writing different states for each HTML template page (like mentioned below).
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'pages/home.html',
controller: 'homeController',
controllerAs: 'home'
})
.state('viz', {
url: '/viz',
templateUrl: 'pages/viz.html',
controller: 'vizController',
controllerAs: 'viz'
})
.state('about', {
url: '/about',
templateUrl: 'pages/about.html',
controller: 'aboutController',
controllerAs: 'about'
})....
Any help is much appreciated.
That should not be so difficult, check for example this:
Angular UI-Router dynamic routing based on slug from API Ajax Call. Load view based on slug
We can use $stateParams and templateProvider to
.state('general', {
url: '/{type}',
//templateUrl: 'pages/home.html',
templateProvider: ['$stateParams', '$templateRequest',
function($stateParams, $templateRequest)
{
var tplName = "pages/" + $stateParams.type + ".html";
return $templateRequest(tplName);
}
],
// general controller instead of home
//controller: 'homeController',
controller: 'generalController',
controllerAs: 'ctrl'
We can also restrict the parameter type to be just one of the expected values, see:
url: '/{type:(?:home|viz|about)}',
Angular js - route-ui add default parmeter
There is also very similar Q & A with working plunker and more details:
AngularJS ui-router - two identical route groups
Another examples could be found here:
Trying to Dynamically set a templateUrl in controller based on constant
Angular UI-router and using dynamic templates

How can I use the UI router without changing the URL?

I am using the angular UI state router using this example:
http://plnkr.co/edit/IzimSVsstarlFviAm7S7?p=preview. The router looks like this it has different urls for each state:
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
templateUrl: 'partial-home.html'
})
// nested list with custom controller
.state('home.list', {
url: '/list',
templateUrl: 'partial-home-list.html',
controller: function($scope) {
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
// nested list with just some random string data
.state('home.paragraph', {
url: '/paragraph',
template: 'I could sure use a drink right now.'
})
// ABOUT PAGE AND MULTIPLE NAMED VIEWS =================================
.state('about', {
url: '/about',
views: {
'': { templateUrl: 'partial-about.html' },
'columnOne#about': { template: 'Look I am a column!' },
'columnTwo#about': {
templateUrl: 'table-data.html',
controller: 'scotchController'
}
}
});
I would like to implement the UIrouter without changing the urls:at the moment the url changes when I change the state. Suppose I am trying to create a page where I have to add a parameter how can I pass on the parameter?
You can not do that. Only one way is custom implementation of routing. I made one time something like that. All containers for all subpages were fixed. Content was dynamically loaded using $http post. Changes were detected by listening of visible ID of container. A lot of stupid work. Most easier is to use ui - routing.

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.

Migrate from ngRoute to ui-router

Needs some guidance with respect to migrating my ngRoute configuration to a ui.router configuration. Currently I have one main template (index.html) and it has an ng-view where all views are injected. My current ngRoute config is as follows:
app.config(function ($routeProvider) {
$routeProvider
.when('/login', {
templateUrl: 'app/views/login.html',
controller: 'LoginCtrl'
})
.when('/contact', {
templateUrl: 'app/views/contact.html',
controller: 'ContactCtrl'
})
.when('/notification', {
templateUrl: 'app/views/notification.html',
controller: 'NotificationCtrl'
})
.otherwise({
redirectTo: '/login'
});
I now want to define a second place in index.html where I can inject some view content - not a nested view, but rather another ng-view (or ui-view in ui-router terminology). The original ng-view section is the default one (currently just for /login and /contact), and the new one is just for specific routes (currently just '/notification' but maybe others in the future). Lets call the new ui-view 'notification-view'.
I've gone through much of the ui-router documentation and still am unsure of how to migrate the above to the new ui.router config. Can someone get me started or point me toward some decent examples?
Update:
Ok, here is where I am. I've adding some states and a new ui-view to my index.html page. See below:
<div class="container">
<div id="header"></div>
<div data-ui-view></div>
<div data-ui-view="notification-view"></div>
</div>
My routing is now:
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'app/views/login.html',
controller: 'LoginCtrl'
})
.state('contact', {
url: '/contact',
templateUrl: 'app/views/contact.html',
controller: 'ContactCtrl'
})
.state('notification', {
url: '/notification',
views: {
"notification-view": {
templateUrl: 'app/views/notification.html',
controller: 'NotificationCtrl'
}
}
});
});
This seems to work ok for the most part. When the url /notification is triggered, the app is routed to the NotificationCtrl and renders ui-view content into the notification-view. However the only problem is that the ui content in the main (unnamed) ui-view is lost. I would like whatever is already rendered in the main ui-view to be untouched, and only target the notification-view. Is this possible? Does it have to instead be a nested-view?
When using ui.router, you should think in terms of states rather than routes. So instead of the $routeProvider you instead inject $stateProvider, plan out various states and work from there . So from your example above, we convert it to:
app.config(function ($stateProvider,$urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('login', {
url:'/login',
templateUrl: 'app/views/login.html',
controller: 'LoginCtrl'
})
.state('contact', {
url:'/contact',
templateUrl: 'app/views/contact.html',
controller: 'ContactCtrl'
})
.state('notification', {
url:'/notification',
templateUrl: 'app/views/notification.html',
controller: 'NotificationCtrl'
});
}
There's alot of methods for adding a "sub-view" to uirouter, one method is by adding a child state.
$stateProvider
.state('login', {
url:'/login',
templateUrl: 'app/views/login.html',
controller: 'LoginCtrl'
})
.state('login.error', {
url:'/login',
templateUrl: 'app/views/login-error-subview.html',
controller: 'LoginErrorCtrl'
})
Also as $stateProvider doesnt provide a default state handler, you will also need to inject in $urlRouterProvider. This is a provider that also comes with ui-router that is tasked with the responsibility of watching $location for changes.
The thing with ui-router is that you won't see a huge difference compared to the built-in route provider and ease of use it brings until you start using sub-states and stacked-states.
In your example above, ui.router wouldnt know what templte to use tor the ui-view and thus leaves it empty. You can give it a template and thus becomes:
...
.state('notification', {
url: '/notification',
views: {
'':{
templateUrl: 'app/views/notification-main.html',
controller: ''
}
'notification-view': {
templateUrl: 'app/views/notification.html',
controller: 'NotificationCtrl'
}
}
...
But from what I'm getting you want the login and contact to have the notification in it. So ideally you'd create a notification child state for each, as right now there is now way to declare wildcard or multiple parents for a child-state. Hopefully when v1.0 comes out there'll be support for this use-case already.
Below is a link from the docs that will get you upto speed:
https://github.com/angular-ui/ui-router/wiki/URL-Routing
https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views

How to make tabs in angularJS have separate controllers?

Right now i am using routeProvider to change between views which works awesome. But now i want to create a view which contains 4 different tabs which should contain 4 different controllers. ive read here that it could be done with stateProvider:
Angular ui tab with seperate controllers for each tab
here is my code:
var WorkerApp = angular.module("WorkerApp", ["ngRoute", 'ngCookies', "ui.bootstrap", "ngGrid", 'ngAnimate', 'ui.router']).config(function ($routeProvider, $stateProvider) {
$routeProvider.
when('/login', {
templateUrl: 'Home/Template/login', resolve: LoginCtrl.resolve
})
.when('/register', { templateUrl: 'Home/Template/register', resolve: RegisterCtrl.resolve })
.when('/', { templateUrl: 'Home/Template/main', resolve: MainCtrl.resolve })
.when('/profile', { templateUrl: 'Home/Template/profile', controller: "ProfileController" })
.when('/contact', { templateUrl: 'Home/Template/contact', controller: "ContactController" })
$stateProvider.state('tabs', {
abstract: true,
url: '/profile',
views: {
"tabs": {
controller: "ProfileController",
templateUrl: 'Home/Template/profile'
}
}
}).state('tabs.tab1', {
url: '/profile', //make this the default tab
views: {
"tabContent": {
controller: "ProfileController",
templateUrl: 'Home/Template/profile'
}
}
})
.state('tabs.tab2', {
url: '/tab2',
views: {
"tabContent": {
controller: 'Tab2Ctrl',
templateUrl: 'tab2.html'
}
}
});
});
but i cant get it really to work because default of routeprovider is set to send over to work because my routeprovider is sending over to "/" on default, which makes "/tabs" invalid. so i cant actully figure out if it is possible to switch to states on specific url. Or change state on specific URL in routeProvider?
I can't tell you for sure exactly what's wrong with the code you've provided, but I'm using Angular UI-Router with the same use case you described, and it's working for me. Here's how I have it configured and how it's different from your configuration:
I don't use $routeProvider at all (none of your $routeProvider.when statements). I'm pretty sure you should not be using $routeProvider since you're using $stateProvider.
I have one use of the $urlRouterProvider with an 'otherwise' statement to specify a default URL:
$urlRouterProvider.otherwise("/home");
My calls to $stateProvider.state is a little different from yours. Here's the one for the parent view of the tabs:
$stateProvider.state('configure', {
url: "/configure",
templateUrl: 'app/configure/configure.tpl.html',
controller: 'ConfigureCtrl'
});
Here's an example of the child state (really the same except for the state name being parent.child format, which you already have in your code; and I added a resolve block but you could have that on the parent as well):
$stateProvider.state('configure.student', {
url: "/student",
templateUrl: 'app/configure/student/configure.student.tpl.html',
controller: 'ConfigureStudentCtrl',
resolve: {
storedClassCode: function($q, user, configureService) {
return configureService.loadMyPromise($q, user);
}
}
});
Also, I'm using version 0.2.8 of Angular UI-Router with version 1.2.9 of Angular. I think this would work with any version of Angular 1.2.0 or later.

Resources