I'm starting using angularjs for my new websites, so I'm a beginner.
I have a problem, which I can't change the value from my $scope inside my controller after the view was called.
I'm using ui-router to multiple views.
I explain in this example:
<html lang="pt" ng-app="myApp">{...}
<header ng-controller="siteHeader"><div ng-show="mySlogan"></div></header><div ui-view="content"></div>
In my js:
var app = angular.module('myApp', ['ui.router']); app.config(['$locationProvider','$stateProvider','$urlRouterProvider'
,function($locationProvider,$stateProvider,$urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('home',{
url: '/',
views: {
'content':{
templateUrl: 'templates/main.html',
controller: 'siteHeader'
}
}
})
.state('login',{
url: '/login',
views: {
'content':{
templateUrl: 'templates/login.html',
controller: 'siteHeader'
}
}
});}]);
app.controller('siteHeader',['$scope','$location',function($scope, $location){
if($location.path()=="/")
$scope.mySlogan = true;
else
$scope.mySlogan = false;}]);
The controller works at first time as page is load, but when the path was changed my $scope.mySlogan does nothing.
What I'm doing wrong?
Use the $state service instead of $location and get the URL as following :
$state.url
Then, try to create a dedicated controller for each route. This will avoid using extensively conditions just to match specific route's template requirements.
The code is only executed once in your controller assigned to <header>. The controllers assigned to your views are just other instances of siteHeader controller and define a new mySlogan variable in their own scope. So, changing the value there won't affect the value in the header scope.
To solve your problem, you could watch the location path:
$scope.$watch(
function() {
return $location.path();
}, function (newValue) {
if (newValue === '/')
$scope.mySlogan = true;
else
$scope.mySlogan = false;
});
Or a better way would be to listen to the ui-router events:
app.controller('siteHeader',['$scope',
function($scope){
$scope.$on('$stateChangeSuccess',
function(event, toState) {
if ( toState.includes('home') )
$scope.mySlogan = true;
else
$scope.mySlogan = false;
});
}]);
You need to assign the controller only to your sideHeader and not to your actual views.
Related
I am trying to bring to my homepage a custom directive which will print me some output.
In the network tab in my devtools I just saw that my controller loads twice.
controller:
var homeController = function($log,leaguesFactory){
var self = this;
self.leagues = [];
leaguesFactory.loadLeagues()
.then(function(leagues){
self.leagues = leagues.data.Competition;
});
self.message= 'test message';
};
directive:
var leaguesTabs = function(){
return {
restrict : 'E',
templateUrl : 'app/home/leagues-tabs.tpl.php',
scope: {
leagues: '='
},
controller: 'homeController',
controllerAs: 'homeCtrl'
};
};
ui-router states:
$stateProvider
.state('home',{
url : '/',
templateUrl : 'app/home/home.tpl.php',
controller : 'homeController',
controllerAs: 'homeCtrl'
})...
I just want to use my homeCtrl in the directive, but it seems that the state provider loads it also and make it load twice. If I remove the controller from the directive then I don't get access to the homeCtrl, if I remove the homeCtrl from the stateprovider than I don't have access in the home.tpl.php
home.tpl.php:
<div>
<leagues-tabs></leagues-tabs>
</div>
any idea?
Actually problem related to next steps:
ui-router start handling url '/'
ui-router create an instance of 'homeController'
ui-router render the view 'app/home/home.tpl.php'
Angular see usage a custom directive - 'leagues-tabs'
'leagues-tabs' directive create an instance of 'homeController'
'leagues-tabs' render the view 'app/home/home.tpl.php'
You can follow any of next possible solutions:
Change controller for 'leagues-tabs' to something special
Remove controller usage from ui-router state definition
You can try this one http://plnkr.co/edit/LG7Wn5OGFrAzIssBFnEE?p=preview
App
var app = angular.module('app', ['ui.router', 'leagueTabs']);
UI Router
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/leagues');
$stateProvider
.state('leagues', {
url: '/leagues',
templateUrl: 'partial-leagues.html',
controller: 'LeaguesController',
controllerAs: 'ctrl'
});
}]);
Controller
app.controller('LeaguesController', ['$http', function($http) {
var self = this;
$http.get('leagues.json').success(function(data){
self.leagues = data;
})
}]);
View
<div>
<league-tabs leagues="ctrl.leagues"></league-tabs>
</div>
Directive
var leagueTabs = angular.module('leagueTabs', []);
leagueTabs.directive('leagueTabs', function(){
return {
restrict : 'E',
templateUrl : 'partial-league-tabs.html',
scope: {
leagues: '='
},
controller: 'LeagueTabsController',
controllerAs: 'leagueTabs'
}
});
leagueTabs.controller('LeagueTabsController', function($scope){
var self = this
$scope.$watch('leagues', function(leagues){
self.leagues = leagues;
})
})
Directive View
<div>
<ul ng-repeat="league in leagueTabs.leagues">
<li>{{league.name}}</li>
</ul>
</div>
I want to resolve some value before I load the first page of my application, but it kept telling me
Unknown provider: programClassSummaryProvider <- programClassSummary <- HomeCtrl
I pretty sure I did it correctly, because I did the same thing for any other controller and routing. but it is not working for my homepage controller.
It seems like it load the controller first, before it is resolved in the routing. Anything wrong with my code?
In routing.js
$stateProvider
.state('home', {
url: '/home',
controller: 'HomeCtrl',
controllerAs: 'vm',
templateUrl: 'index_main.html',
resolve: {
programClassSummary: ['GroupDataFactory', function (groupDf) {
return groupDf.getProgramClassSummary();
}]
},
ncyBreadcrumb: {
skip: true
}
});
in controller.js
angular
.module('issMccApp')
.controller('HomeCtrl', homeCtrl);
homeCtrl.$inject = ['$scope', '$location', '$state', '$auth', 'programClassSummary'];
/* #ngInject */
function homeCtrl($scope, $location, $state, $auth, programClassSummary) {
var vm = this;
vm.isAuthenticated = isAuthenticated;
vm.programClassSummary = programClassSummary;
if (!$auth.isAuthenticated()) {
$state.go('login');
return;
}
function isAuthenticated() {
return $auth.isAuthenticated();
}
}
in factory.js
function getProgramClassSummary(showAll) {
var query = "";
if (showAll)
query = APIConfigObj.base_url + '/api/group/infor/programclasssummary?all=1';
else
query = APIConfigObj.base_url + '/api/group/infor/programclasssummary';
return $http.get(query)
.success(function (result) {
return result;
})
.error(function (err) {
return err;
})
}
I'd say, we really have to distinguish the UI-Router state world, and angular itself. Reason why is clearly defined here (extracted $resolve from UI-Router API documentation):
$resolve
resolve(invocables, locals, parent, self)
Resolves a set of invocables. An invocable is a function to be invoked via $injector.invoke(), and can have an arbitrary number of dependencies. An invocable can either return a value directly, or a $q promise. If a promise is returned it will be resolved and the resulting value will be used instead. Dependencies of invocables are resolved (in this order of precedence)
from the specified locals
from another invocable that is part of this $resolve call
from an invocable that is inherited from a parent call to $resolve (or recursively
from any ancestor $resolve of that parent).
There is a wroking plunker, which uses this index.html
<body ng-controller="RootCtrl">
a summary for a root:
<pre>{{summary}}</pre>
<ul>
<li>home
<li>other
</ul>
<div ui-view=""></div>
So, here we use some RootCtrl, which won't go through state machine UI-Router, it is angular basic stuff
The root controller must be defined as
.controller('RootCtrl', ['$scope', 'GroupDataFactory', function ($scope, groupDf) {
$scope.summary = groupDf.getProgramClassSummary();
}])
For a state home, we can use different approach, in fact the same as above (simplifed version below)
.state('home', {
url: "/home",
templateUrl: 'tpl.home.html',
resolve: {
programClassSummary: ['GroupDataFactory', function (groupDf) {
return groupDf.getProgramClassSummary();
}]
},
controller: 'HomeCtrl',
})
And its controller is now able to consume the locals
.controller('HomeCtrl', ['$scope', 'programClassSummary', function ($scope, summary) {
$scope.summaryForHome = summary;
}])
Check it in action here
I just started with angularJS and I have a question:
How can I access a variable defined with $rootScope in a templateUrl function?
Here is my code:
myApp.config(['$routeProvider',
function($routeProvider, $rootScope) {
$routeProvider.
when( '/', {
templateUrl: 'partials/login.html',
controller: 'loginCtrl'
}).
when( '/home', {
templateUrl: function($rootScope){
console.log($rootScope.utilisateur.user.role_id);
if ($rootScope.utilisateur.user.role_id==2){
return 'partials/home.html';
}
else return 'partials/login.html';
},
controller: 'homeCtrl'
}).
otherwise({redirectTo:'/'});
}]);
It tells me that utilisateur is undefined.
I defined it in the index controller:
$rootScope.utilisateur = null;
$rootScope.rapports = null;
And then in the LoginCtrl:
var user = Authentification.login(email,password);
user.success(function(response){
$rootScope.utilisateur = response;
console.log($rootScope.utilisateur);
$location.path('/home');
});
You cannot use the $rootScope inside of the config block, as the config block runs before the $rootScope is created. Constants and providers may be used inside of the config block instead. If constants are not an option for you, you may want to redirect to the correct url inside of your homeCtrl.
[EDIT] Added possible solution from comment below:
Option 1: Have 2 different routes
/admin/home
/home
Option 2: Switch templates according to permission inside of controller/view
home.html
<div ng-switch="utilisateur.user.role_id">
<div ng-switch-when="2">
<!-- is admin -->
</div>
<div ng-switch-default>
<!-- not admin -->
</div>
</div>
Not the ideal solution, but it'd work for what you are trying to do, based on your comments below
Your problem seems like you have two different views, and on condition base you have to redirect views.
Pass the parameters in url like from your views (Create/Edit link etc.) As i have set the cookie on login and accessed here as a parameters or you can use different way to access the parameters.
''
And your config in $routeProvider use like this:
$routeProvider.when("/editTest/:ID/:flagTab",
{
templateUrl: function (params) {
var flag = params.flagTab;
if (flag == 'tabPanelView') {
return '/apps/templates/editTest.html';
}
else {
return '/apps/templates/editTestPageView.html';
}
},
controller: 'EditTestController'
});.
Refere a link swtiching views in routeProvider based on condition
Instead of describing different ways to achieve what you would like to, the code snippet below answers the actual question that was asked:
How can I access a variable defined with $rootScope in a templateUrl function?
The answers above and here imply there is no way to reference $rootScope within the config/$routeProvider. While that may strictly be true, there is a simple way to access the $rootScope through $routeProvider. Below is how to do this:
Sample HTML:
<div ng-app="myApp">
<div ng-controller="masterController">
<script type="text/ng-template" id="home.html">{{something}}</script>
Page
<div ng-view></div>
</div>
</div>
Sample javascript:
var myApp = angular.module('myApp',[],function($routeProvider) {
$routeProvider
.when('/home',{templateUrl:'home.html'})
.when('/page',
{
template:'<p>{{something}}</p>',
controller:'masterCtrlWrapper'
})
.otherwise({redirectTo:'/home'});
});
myApp.controller('masterCtrlWrapper', function($rootScope)
{ $rootScope.changeVariable(); });
myApp.controller('masterController', function($rootScope)
{
$rootScope.something = 'This is the $rootScope talking.'
$rootScope.pressCount = 0;
$rootScope.changeVariable = function()
{ $rootScope.something = "This function was run " + $rootScope.pressCount++ + " times."; };
});
Like others have said, $rootScope doesn't exist yet, but unlike their answers, it doesn't at all mean you can't use it at all, you just have to code-in the wait.
Here is your example working but just printing since we dont have the templates.
myApp
.provide('home', function() {
var $rootScope = null;
this.templateUrl = function() {
var check =
$rootScope.utilisateur &&
$rootScope.utilisateur.user.role_id
;
console.log(check);
return (check) ? 'partials/home.html' : 'partials/login.html';
};
this.controller = 'homeCtrl';
this.resolve = {load:['$rootScope', function(fetched) { $rootScope = fetched; }]};
this.$get = function() { };
})
.config(['$routeProvider', 'homeProvider', function($routeProvider, homeProvider) {
$routeProvider
.when('/', {
templateUrl : 'partials/login.html',
controller : 'loginCtrl'
})
.when('/home', homeProvider)
.otherwise({redirectTo:'/'})
;
}])
;
I am migrating my AngularJS based app to use ui-router instead of the built in routing. I have it configured as shown below
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl : 'views/home.html',
data : { pageTitle: 'Home' }
})
.state('about', {
url: '/about',
templateUrl : 'views/about.html',
data : { pageTitle: 'About' }
})
});
How can I use the pageTitle variable to dynamically set the title of the page? Using the built in routing, I could do
$rootScope.$on("$routeChangeSuccess", function(currentRoute, previousRoute){
$rootScope.pageTitle = $route.current.data.pageTitle;
});
and then bind the variable in HTML as shown below
<title ng-bind="$root.pageTitle"></title>
Is there a similar event that I can hook into using ui-router? I noticed that there are 'onEnter' and 'onExit' functions but they seem to be tied to each state and will require me to repeat code to set the $rootScope variable for each state.
Use $stateChangeSuccess.
You can put it in a directive:
app.directive('updateTitle', ['$rootScope', '$timeout',
function($rootScope, $timeout) {
return {
link: function(scope, element) {
var listener = function(event, toState) {
var title = 'Default Title';
if (toState.data && toState.data.pageTitle) title = toState.data.pageTitle;
$timeout(function() {
element.text(title);
}, 0, false);
};
$rootScope.$on('$stateChangeSuccess', listener);
}
};
}
]);
And:
<title update-title></title>
Demo: http://run.plnkr.co/8tqvzlCw62Tl7t4j/#/home
Code: http://plnkr.co/edit/XO6RyBPURQFPodoFdYgX?p=preview
Even with $stateChangeSuccess the $timeout has been needed for the history to be correct, at least when I've tested myself.
Edit: Nov 24, 2014 - Declarative approach:
app.directive('title', ['$rootScope', '$timeout',
function($rootScope, $timeout) {
return {
link: function() {
var listener = function(event, toState) {
$timeout(function() {
$rootScope.title = (toState.data && toState.data.pageTitle)
? toState.data.pageTitle
: 'Default title';
});
};
$rootScope.$on('$stateChangeSuccess', listener);
}
};
}
]);
And:
<title>{{title}}</title>
Demo: http://run.plnkr.co/d4s3qBikieq8egX7/#/credits
Code: http://plnkr.co/edit/NpzQsxYGofswWQUBGthR?p=preview
There is a another way of doing this by combining most of the answers here already. I know this is already answered but I wanted to show the way I dynamically change page titles with ui-router.
If you take a look at ui-router sample app, they use the Angular .run block to add the $state variable to $rootScope.
// It's very handy to add references to $state and $stateParams to the $rootScope
// so that you can access them from any scope within your applications.
// For example, <li ng-class="{ active: $state.includes('contacts.list') }">
// will set the <li> to active whenever 'contacts.list' or one of its
// decendents is active.
.run([ '$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}])
With this defined, you can then easily dynamically update your page title with what you have posted but modified to use the defined state:
Setup the state the same way:
.state('home', {
url: '/home',
templateUrl : 'views/home.html',
data : { pageTitle: 'Home' }
})
But edit the html a bit...
<title ng-bind="$state.current.data.pageTitle"></title>
I can't say this is any better than the answers before, but it was easier for me to understand and implement.
The angular-ui-router-title plugin makes it easy to update the page title to a static or dynamic value based on the current state. It correctly works with browser history, too.
$stateChangeSuccess is now deprecated in UI-Router 1.x and disabled by default. You'll now need to use the new $transition service.
A solution isn't too difficult once you understand how $transition works. I got some help from #troig in understanding it all. Here's what I came up with for updating the title.
Put this in your Angular 1.6 application. Note that I'm using ECMAScript 6 syntax; if you are not, you'll need e.g. to change let to var.
.run(function($transitions, $window) {
$transitions.onSuccess({}, (transition) => {
let title = transition.to().title;
if (title) {
if (title instanceof Function) {
title = title.call(transition.to(), transition.params());
}
$window.document.title = title;
}
});
Then just add a title string to your state:
$stateProvider.state({
name: "foo",
url: "/foo",
template: "<foo-widget layout='row'/>",
title: "Foo Page""
});
That will make the words "Foo Page" show up in the title. (If a state has no title, the page title will not be updated. It would be a simple thing to update the code above to provide a default title if a state does not indicate one.)
The code also allows you to use a function for title. The this used to call the function will be the state itself, and the one argument will be the state parameters, like this example:
$stateProvider.state({
name: "bar",
url: "/bar/{code}",
template: "<bar-widget code='{{code}}' layout='row'/>",
title: function(params) {
return `Bar Code ${params.code}`;
}
});
For the URL path /bar/code/123 that would show "Bar Code 123" as the page title. Note that I'm using ECMAScript 6 syntax to format the string and extract params.code.
It would be nice if someone who had the time would put something like this into a directive and publish it for everyone to use.
Attaching $state to $rootscope to use anywhere in the app.
app.run(['$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
// It's very handy to add references to $state and $stateParams to the $rootScope
// so that you can access them from any scope within your applications.For example,
// <li ng-class="{ active: $state.includes('contacts.list') }"> will set the <li>
// to active whenever 'contacts.list' or one of its decendents is active.
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}
]
)
<title ng-bind="$state.current.name + ' - ui-router'">about - ui-router</title>
I found this way really easy:
.state('app.staff.client', {
url: '/client/mine',
title: 'My Clients'})
and then in my HTML like this:
<h3>{{ $state.current.title }}</h3>
Just update window.document.title:
.state('login', {
url: '/login',
templateUrl: "/Login",
controller: "loginCtrl",
onEnter: function($window){$window.document.title = "App Login"; }
})
That way 'ng-app' does not need to move up to the HTML tag and can stay on the body or lower.
I'm using ngMeta, which works well for not only setting page title but descriptions as well. It lets you set a specific title/description for each state, defaults for when a title/description is not specified, as well as default title suffixes (i.e., ' | MySiteName') and author value.
$stateProvider
.state('home', {
url: '/',
templateUrl: 'views/home.html',
controller: 'HomeController',
meta: {
'title': 'Home',
'titleSuffix': ' | MySiteName',
'description': 'This is my home page description lorem ipsum.'
},
})
You are actually really close with your first answer/question. Add your title as a data object:
.state('home', {
url: '/home',
templateUrl : 'views/home.html',
data : { pageTitle: 'Home' }
})
In your index.html bind the data directly to the page title:
<title data-ng-bind="$state.current.data.pageTitle + ' - Optional text'">Failsafe text</title>
I ended up with this combination of Martin's and tasseKATT's answers - simple and without any template related stuff:
$rootScope.$on("$stateChangeSuccess", function (event, toState) {
$timeout(function () { // Needed to ensure the title is changed *after* the url so that history entries are correct.
$window.document.title = toState.name;
});
});
Why not just:
$window.document.title = 'Title';
UPDATE: Full Directive Code
var DIRECTIVE = 'yourPageTitle';
yourPageTitle.$inject = ['$window'];
function yourPageTitle($window: ng.IWindowService): ng.IDirective {
return {
link: (scope, element, attrs) => {
attrs.$observe(DIRECTIVE, (value: string) => {
$window.document.title = value;
});
}
}
}
directive(DIRECTIVE, yourPageTitle);
Then in every page you would just include this directive:
<section
your-page-title="{{'somePage' | translate}}">
If you are using ES6, this works just fine :).
class PageTitle {
constructor($compile, $timeout) {
this.restrict = 'A';
this._$compile = $compile;
this.$timeout = $timeout;
}
compile(element) {
return this.link.bind(this);
}
link(scope, element, attrs, controller) {
let defaultTitle = attrs.pageTitle ? attrs.pageTitle : "My Awesome Sauce Site";
let listener = function(event, toState) {
let title = defaultTitle;
if (toState.data && toState.data.title) title = toState.data.title + ' | ' + title;
$('html head title').text(title);
};
scope.$on('$stateChangeStart', listener);
}
}
export function directiveFactory($compile) {
return new PageTitle($compile);
}
directiveFactory.injections = ['$compile', '$timeout'];
export default PageTitle;
Maybe you can try this directive.
https://github.com/afeiship/angular-dynamic-title
Here is the example:
html:
<title dynamic-title>Title</title>
State1 page
State2 page
javascript:
var TestModule = angular.module('TestApp', ['ui.router','nx.widget'])
.config(function ($stateProvider, $urlRouterProvider) {
//
// For any unmatched url, redirect to /state1
$urlRouterProvider.otherwise("/state1");
//
// Now set up the states
$stateProvider
.state('state1', {
url: "/state1",
templateUrl: "partials/state1.html",
data:{
pageTitle:'State1 page title11111'
}
})
.state('state2', {
url: "/state2",
templateUrl: "partials/state2.html",data:{
pageTitle:'State2 page title222222'
}
});
})
.controller('MainCtrl', function ($scope) {
console.log('initial ctrl!');
});
For Updated UI-Router 1.0.0+ versions,
(https://ui-router.github.io/guide/ng1/migrate-to-1_0)
Refer to following code
app.directive('pageTitle', [
'$rootScope',
'$timeout',
'$transitions',
function($rootScope, $timeout,$transitions) {
return {
restrict: 'A',
link: function() {
var listener = function($transitions) {
var default_title = "DEFAULT_TITLE";
$timeout(function() {
$rootScope.page_title = ($transitions.$to().data && $transitions.$to().data.pageTitle)
? default_title + ' - ' + $transitions.$to().data.pageTitle : default_title;
});
};
$transitions.onSuccess({ }, listener);
}
}
}
])
Add following to your index.html:
<title page-title ng-bind="page_title"></title>
if (abp.auth.hasPermission('Center.Category.GroupItem')) {
$stateProvider.state('groupItems', {
title: 'GroupItems',
url: '/groupItems',
templateUrl: '~/App/product/views/center/groupItem/index.cshtml'
controller: 'app.product.views.center.groupItem.index as vm'
});
}
<title>{{$state.current.title ? $state.current.title : 'MiniShop'}}</title>
Is it possible to [execute a function] e.g. open a modal dialog window from the routeProvider when a certain route is requested?
myApp.config(function($routeProvider) {
$routeProvider
.when('/home',
{
controller: 'HomeCtrl',
templateUrl: 'Home/HomeView.html'
}
).when('/profile/:userId/changepwd',
function(){
$dialog.messageBox(title, msg, btns)
.open()
.then(function(result){
alert('dialog closed with result: ' + result);
});
}
).otherwise({ redirectTo: '/home' });
});
PS: I want to cancel a route and instead open a dialog box. Opening the dialog box is not the only issue. Cancelling the route is the major issue.
You can pass your function as dependency in resolve and it will wait until dependency is resolved and when your dialog ends then change the route and modify history as you wish using $location
var app = angular.module('myApp', [])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
template: ' ',
controller: //empty function,
resolve: {
data1 : function($dialog, $location) {
var promise = $dialog.messageBox(title, msg, btns)
.open()
.then(function(result){
alert('dialog closed with result: ' + result);
//Use [$location][1] to change the browser history
});
return promise;
}
}
});
}]);
Building on Rishabh's answer, and using sergey's location.skipReload from this Angular Issue you can use the following to create a dialog on route-change, defer the url-change indefinitely (in effect 'cancelling' the route change), and rewrite the URL bar back to '/' without causing another reload:
//Override normal $location with this version that allows location.skipReload().path(...)
// Be aware that url bar can now get out of sync with what's being displayed, so take care when using skipReload to avoid this.
// From https://github.com/angular/angular.js/issues/1699#issuecomment-22511464
app.factory('location', [
'$location',
'$route',
'$rootScope',
function ($location, $route, $rootScope) {
$location.skipReload = function () {
var lastRoute = $route.current;
var un = $rootScope.$on('$locationChangeSuccess', function () {
$route.current = lastRoute;
un();
});
return $location;
};
return $location;
}
]);
app
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/home', {
controller: 'HomeCtrl',
templateUrl: 'Home/HomeView.html'
})
.when('/profile/:userId/changepwd', {
template: ' ',
controller: '',
resolve: {
data1: function($dialog, location, $q){
$dialog.messageBox(title, msg, btns)
.open()
.then(function(result){
//fires on modal close: rewrite url bar back to '/home'
location.skipReload().path('/home');
//Could also rewrite browser history here using location?
});
return $q.defer().promise; //Never resolves, so template ' ' and empty controller never actually get used.
}
}
})
.otherwise({
redirectTo: '/'
});
This feels like it leaks unresolved promises, and there may be a neater solution, but this worked for my purposes.
You can redirect the route to the same partial. You can do this by watching for a change in route using the following code. You can also show a dialog from here.
$rootScope.$on( '$routeChangeStart', function(event, next, current) {
if ( next.templateUrl == "xyz.html" ) {
//other validation logic, if it fails redirect user to the same page
$location.path( "/home" );
}
});