AngularJS UI路由器-在不重新加载状态的情况下更改URL

17 浏览
0 Comments

AngularJS UI路由器-在不重新加载状态的情况下更改URL

目前我们的项目正在使用默认的$routeProvider,我在使用这个\"hack\"来在不重新加载页面的情况下改变url

services.service('$locationEx', ['$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;
}]);

同时在controller中:

$locationEx.skipReload().path("/category/" + $scope.model.id).replace();

我正在考虑使用 ui-router来嵌套路由,但是在ui-router中找不到这个东西。

是否可能 - 使用angular-ui-router实现同样的功能?

为什么需要这个?

让我用一个例子来解释:

创建一个新类别的路由是/category/new

SAVE后,我会展示success-alert,然后我想把路由从/category/new变成/caterogy/23(23是存储在数据库中的新项的ID)。

admin 更改状态以发布 2023年5月24日
0
0 Comments

好的,问题解决了 🙂
Angular UI Router有这个新方法,$urlRouterProvider.deferIntercept()
https://github.com/angular-ui/ui-router/issues/64

基本上就是这样:

angular.module('myApp', [ui.router])
  .config(['$urlRouterProvider', function ($urlRouterProvider) {
    $urlRouterProvider.deferIntercept();
  }])
  // then define the interception
  .run(['$rootScope', '$urlRouter', '$location', '$state', function ($rootScope, $urlRouter, $location, $state) {
    $rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {
      // Prevent $urlRouter's default handler from firing
      e.preventDefault();
      /** 
       * provide conditions on when to 
       * sync change in $location.path() with state reload.
       * I use $location and $state as examples, but
       * You can do any logic
       * before syncing OR stop syncing all together.
       */
      if ($state.current.name !== 'main.exampleState' || newUrl === 'http://some.url' || oldUrl !=='https://another.url') {
        // your stuff
        $urlRouter.sync();
      } else {
        // don't sync
      }
    });
    // Configures $urlRouter's listener *after* your custom listener
    $urlRouter.listen();
  }]);

我认为这个方法目前只包括在Angular UI Router主分支中,这个版本有可选参数(顺便说一下,它们很好用)。需要从源代码中克隆和构建。

grunt build

文档也可以从源代码中访问,通过

grunt ngdocs

(它们构建到/site目录中)//更多信息请查阅README.MD

似乎还有另一种方法可以实现这一点,通过动态参数(我没有使用过)。
非常感谢nateabele。


顺便提一下,这里是Angular UI Router的可选参数,我与上面的方法一起使用:

angular.module('myApp').config(['$stateProvider', function ($stateProvider) {    
  $stateProvider
    .state('main.doorsList', {
      url: 'doors',
      controller: DoorsListCtrl,
      resolve: DoorsListCtrl.resolve,
      templateUrl: '/modules/doors/doors-list.html'
    })
    .state('main.doorsSingle', {
      url: 'doors/:doorsSingle/:doorsDetail',
      params: {
        // as of today, it was unclear how to define a required parameter (more below)
        doorsSingle: {value: null},
        doorsDetail: {value: null}
      },
      controller: DoorsSingleCtrl,
      resolve: DoorsSingleCtrl.resolve,
      templateUrl: '/modules/doors/doors-single.html'
    });
}]);

它的作用是即使一个参数缺失,也能解析状态。
SEO是一个目的,可读性是另一个目的。

在上面的例子中,我想要 doorsSingle 是一个必需参数。不清楚如何定义它们。但多个可选参数一起使用时还是可以正常工作的,所以并不是一个问题。讨论在这里https://github.com/angular-ui/ui-router/pull/1032#issuecomment-49196090

0
0 Comments

你可以简单地使用$state.transitionTo代替$state.go。内部$state.go会自动设置选项{location: true, inherit: true, relative: $state.$current, notify: true},而$state.transitionTo则可以手动设置 notify: false 。例如:

$state.go('.detail', {id: newId}) 

可以被替换为:

$state.transitionTo('.detail', {id: newId}, {
    location: true,
    inherit: true,
    relative: $state.$current,
    notify: false
})

编辑:正如fracz所建议的那样,它可以简单地用以下方式实现:

$state.go('.detail', {id: newId}, {notify: false}) 

0