Angularjs UI bootstrap 打开时临时更改 URL 并在关闭时恢复为原始 URL

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

我想在 ui bootstrap 模态打开时临时更改浏览器 url (后面的页面应该保持原样,只有 url 变化) .当模式关闭时,url 应该恢复到原来的状态。

步骤:

  1. 用户加载页面
    • url : xyz.com/home
  2. 用户点击 link 打开模式
    • url : xyz.com/detail/123
    • 可能的解决方案:将 url 更改为 html5 推送状态
    • 问题:Angular ui-路由器尝试 运行 根据更改后的 url 其路由,最终更改后台页面。
  3. 用户关闭模式
    • url : xyz.com/home
    • 可能的解决方案:html5弹出状态
    • 问题:重新加载后台页面,这会破坏目的

实施示例:Pinterest 图钉及其图钉详细信息弹出窗口。

您可以使用ui-router-extras sticky state来解决您的问题。 link 有一个简单的模态示例。您应该创建两个命名视图,一个用于主要内容(背景),一个用于模式。

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

在路由定义中将状态标记为sticky: true,从您要访问的模态。

.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'
    }
  }
})

同时为 stateChangeSuccess 添加一个事件:

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

所以,当你需要关闭模态时,你可以

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

该解决方案存在小问题。如果您在模式状态下重新加载页面,则应用 ui-view 将为空。

这可以通过 nested state 并使用 onEnter 回调触发模式来实现:

$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
      });
    }
  });

ui-router 的 FAQ 中有 described 这种技术。

这里是plunk。在此示例中,模态的范围被创建为 $rootScope 的子级 - 当没有范围传递给它时默认的 $uibModal 行为。在这种情况下,我们应该使用模态控制器中的服务通过url参数获取数据。

要使 master 和 details URL 看起来像这样 - xyz.com/homexyz.com/detail/123 - 我们应该使用绝对 URL (^/details/:id)子状态。

使用此解决方案,您可以直接打开详细信息 URLs,并且仍然具有正确激活的主要和详细信息状态,因此可以共享详细信息 URL。

我想你可以用 n 个 Silent 模块来实现

https://github.com/garakh/ngSilent

使用$ngSilentLocation.silent('/new/path/'); (一旦你打开模式并在关闭它之后再次)

设法使用 https://github.com/christopherthielen/ui-router-extras/tree/gh-pages/example/stickymodal

实现了这一点