Controller not getting Initialized until user navigated to the particular url - angularjs

.when("/main", {
templateUrl: "main.html",
controller: "MainController"
})
.when("/user/:username",{
templateUrl: "user.html",
controller: "UserController"
})
.otherwise({redirectTo:"/main"});
In User.html i have a button which open a ng-dialog and it has some data from main.html but if the user directly navigated to /user/:username i am not able to render the data from main.html in my ng-dialog.

As per ngRoute, these routes do not have any relation between them. When you move to the route /user/:username, MainController is destroyed and UserController is activated.
If you want to have parent child relationship i.e. activate MainController on activation of /user/:username route, use UI Router.
Code in UI Router would look like:
function ($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/main',
templateUrl: 'main.html',
controller: 'MainController'
})
.state('home.user', {
url: 'user/:username',
templateUrl: 'user.html',
controller: 'UserController'
});
};

Related

My angular page stuck (routing not working) if not used for few minutes (when page is idle for few minutes)

I am using Angular UI Router for my Single page application. It is basically report (Grid + charts). When I route from one page to another it is fine. But if I open page and leave it like that for few minutes and again I try to go to another page by clicking link, it is stuck there. Then I have to refresh the page.
This means if the page is left idle for few minutes then the routing is not happening as it should be.
(function () {
var module = angular.module("app", ["ngAnimate", "ui.router", "ui.bootstrap"]);
module.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/error");
$stateProvider
.state('home', {
url: "/",
templateUrl: "partials/index.html",
controller: "indexController",
controllerAs: "ctrl"
})
.state('weather', {
url: "/weather",
templateUrl: "./partials/weather.html",
controller: "weatherController",
controllerAs: "ctrl"
})
.state('error', {
url: "/error",
templateUrl: "/partials/error.html"
})
.state('horizontalBar', {
url: "/horizontalBar",
templateUrl: "./partials/charts/d3/horizontalBar.html",
controller: "horizontalBarController",
controllerAs: "ctrl"
})
.state('lineChart', {
url: "/lineChart",
templateUrl: "./partials/charts/d3/lineChart.html",
controller: "lineChartController",
controllerAs: "ctrl"
});
});
}());

$state.go not redirecting but its loading the content with 200 OK

Here is the plunker link for the code http://plnkr.co/edit/JwM8t3oNepP3tE1nUXlM?p=info
controller.js
if(($scope.login==='Admin')&&($scope.password==='admin'))
{
$state.go('login.home');
}
script.js
var DailyUsageApp = angular.module('DailyUsageApp', ['ui.router']);
DailyUsageApp.config(function($stateProvider, $locationProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider.state('login', {
url: '/login',
templateUrl: "login.html",
controller: 'authController'
})
.state('login.home', {
url: '/home',
templateUrl: "home.html",
controller: 'homeController'
});
});
The reason your code isn't working is because you are creating hierarchical states, that are not meant to be hierarchical. By naming your state login.home, you are saying that home is a child of login. This means that when you try and go('login.home') ui router is attempting to render the login state as well as the home state as a child. This means that for your current layout to work, the login template must contain its own ui-view tag. The best way to fix this is to simply rename your state to just home, and then use $state.go('home');
There is an updated plunker
The most simple solution is to NOT make state login.home nested under login.
//.state('login.home', {
.state('home', {
url: '/home',
templateUrl: "home.html",
controller: 'homeController'
});
There are also other solutions, like create a target for login.home inside of the login like this:
<div ui-view=""></div
But usually, we do not do that. Just login and then navigate to some other state hierarchy...

ui-router named views with route and url

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.

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

Resources