AngularJS UI路由器-在不重新加载状态的情况下更改URL
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)。
好的,问题解决了 🙂
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
你可以简单地使用$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})