Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS show dialog from routeProvider

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.

like image 647
Tawani Avatar asked May 06 '13 02:05

Tawani


2 Answers

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;
                }
       }
   });
}]);
like image 70
Rishabh Singhal Avatar answered Nov 16 '22 07:11

Rishabh Singhal


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.

like image 44
Crashthatch Avatar answered Nov 16 '22 07:11

Crashthatch