Angularjs UI bootstrap temporarily change URL on open and revert to original URL on close

夙愿已清 提交于 2019-12-05 09:03:41

You can use ui-router-extras sticky state to solve your problem. There is simple example with modal by the link. You should create two named views, one for main content (background) and one for modal.

<div ui-view="app"></div>
<div ui-view="modal"></div>

Mark the state, from what you want to access to modal as sticky: true in route definition.

.state('main', {
  abstract: true,
  url: '/',
  templateUrl: '_layout.html'
})
.state('main.index', {
  url: '',
  sticky: true,
  views: {
    'app': {
      templateUrl: 'index.html'
    }
  }
})
.state('main.login', {
  url: 'login/',
  views: {
    'modal': {
      templateUrl: 'login.html'
    }
  }
})

Also add an event for stateChangeSuccess:

$rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
  if ((from.views && !from.views.modal) || !from.views) {
    $rootScope.from = from;
    $rootScope.fromParams = fromParams;
  }
});

so, when you need to close modal, you can just

$state.go($rootScope.from, $rootScope.fromParams);

There is small problem for that solution. If you reload page on the modal state, then the app ui-view will be empty.

This can be achieved by having a nested state and triggering the modal using onEnter callback:

$stateProvider
  .state('contacts', {
    url: '/home',
    templateUrl: 'home.html',
    controller: function($scope, MyService){
      $scope.contacts = MyService.getContacts();
    }
  })
  .state('contacts.details', {
    url: "^/details/:id", // using the absolute url to not have the "/home" prepended
    onEnter: function($state, $uibModal) {
      var modal = $uibModal.open({
        templateUrl: 'details.html',
        controller: function($scope, $stateParams, MyService) {
            // get data from service by url parameter
            $scope.contact = MyService.getContact($stateParams.id);
        }
      });

      modal.result.finally(function() {
        $state.go('^'); // activate the parent state when modal is closed or dismissed
      });
    }
  });

This technique is described in the ui-router's FAQ.

Here the plunk. In this example the modal's scope is created as a child of the $rootScope - the default $uibModal's behavior when no scope is passed to it. In this case we should use the service in the modal's controller to obtain the data by url parameter.

To have master and details URLs look like these - xyz.com/home and xyz.com/detail/123 - we should use the absolute URL (^/details/:id) in the child state.

Using this solution you can open the detail URLs directly and still have both, master and detail states, activated properly, so sharing the detail URL is possible.

I think you can achive that with ngSilent module

https://github.com/garakh/ngSilent

using $ngSilentLocation.silent('/new/path/'); (once you open modal and again after closing it)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!