AngularJS show dialog from routeProvider
Asked Answered
J

3

6

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.

Janka answered 6/5, 2013 at 2:0 Comment(1)
When you say "cancel" a route, do you mean send the user back where he came from ($window.history.back()) or to redirect him after he is done interacting with the Dialog box ($location.path('/new'))?Wardmote
P
4

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: '&nbsp',
       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;
                }
       }
   });
}]);
Parhelion answered 23/7, 2013 at 23:26 Comment(0)
M
2

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 '&nbsp' 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.

Maseru answered 12/9, 2013 at 14:32 Comment(0)
D
0

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" );
    }          
});
Diplomatist answered 23/7, 2013 at 6:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.