目前我们的项目使用默认$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();
我正在考虑将routeProvider
替换为ui-router
用于嵌套路由,但无法在ui-router
中找到它。
是否可以 - 对angular-ui-router
执行相同的操作?
为什么我需要这个?
让我用一个例子来解释:
创建新类别的路线是/category/new
在SAVE clicking
之后我显示success-alert
并且我想将路由/category/new
更改为/caterogy/23
(23 - 是存储在db中的新项目的ID)
答案 0 :(得分:152)
您只需使用 $state.transitionTo
代替 $state.go
即可。 $state.go
在内部调用 $state.transitionTo
,但会自动将选项设置为 { 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})
答案 1 :(得分:48)
好的,解决了 :) 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路由器的 master 版本中,带有可选参数的那个(也很好,顺便说一句)。它需要克隆并使用
从源代码构建grunt build
也可以通过
从源代码访问文档grunt ngdocs
(它们内置于/ site目录中)// README.MD中的更多信息
似乎还有另一种方法,通过动态参数(我还没有使用过)。 nateabele有很多学分。
作为旁注,这里是Angular UI Router的$ stateProvider中的可选参数,我将其与上述结合使用:
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
答案 2 :(得分:13)
在这个问题上花了很多时间后,这就是我的工作
$state.go('stateName',params,{
// prevent the events onStart and onSuccess from firing
notify:false,
// prevent reload of the current state
reload:false,
// replace the last record when changing the params so you don't hit the back button and get old params
location:'replace',
// inherit the current params on the url
inherit:true
});
答案 3 :(得分:7)
此设置为我解决了以下问题:
.../
更新为.../123
州配置
state('training', {
abstract: true,
url: '/training',
templateUrl: 'partials/training.html',
controller: 'TrainingController'
}).
state('training.edit', {
url: '/:trainingId'
}).
state('training.new', {
url: '/{trainingId}',
// Optional Parameter
params: {
trainingId: null
}
})
调用状态(来自任何其他控制器)
$scope.editTraining = function (training) {
$state.go('training.edit', { trainingId: training.id });
};
$scope.newTraining = function () {
$state.go('training.new', { });
};
培训控制器
var newTraining;
if (!!!$state.params.trainingId) {
// new
newTraining = // create new training ...
// Update the URL without reloading the controller
$state.go('training.edit',
{
trainingId : newTraining.id
},
{
location: 'replace', // update url and replace
inherit: false,
notify: false
});
} else {
// edit
// load existing training ...
}
答案 4 :(得分:3)
如果您只需要更改网址但阻止更改状态:
更改位置(如果要在历史记录中替换,请添加.replace):
this.$location.path([Your path]).replace();
防止重定向到您的州:
$transitions.onBefore({}, function($transition$) {
if ($transition$.$to().name === '[state name]') {
return false;
}
});
答案 5 :(得分:2)
我做了这个,但很久以前版本:UI-router的v0.2.10就像这样::
collection('myDocs')[root/@myAtt = 'one']
答案 6 :(得分:1)
致电
$state.go($state.current, {myParam: newValue}, {notify: false});
仍会重新加载控制器。
为避免这种情况,必须将参数声明为dynamic:
$stateProvider.state({
name: 'myState',
url: '/my_state?myParam',
params: {
myParam: {
dynamic: true,
}
},
...
});
然后,您甚至都不需要notify
,只需致电
$state.go($state.current, {myParam: newValue})
足够了。尼阿托!
当
dynamic
为true
时,对参数值的更改将 不会导致状态进入/退出。解决办法不会 重新获取,也不会重新加载视图。[...]
这对构建很有用 当参数值更改时组件将自行更新的用户界面。
答案 7 :(得分:0)
尝试这样的事情
$state.go($state.$current.name, {... $state.params, 'key': newValue}, {notify: false})
答案 8 :(得分:-6)
我认为你根本不需要ui-router。可用于$location service的文档在第一段中说,“...对$ location的更改会反映到浏览器地址栏中。”它继续说,“它不做什么?当浏览器URL被更改时,它不会导致整页重新加载。”
因此,考虑到这一点,为什么不简单地更改$ location.path(因为该方法既是getter又是setter),具体如下:
var newPath = IdFromService;
$location.path(newPath);
documentation注意到路径应始终以正斜杠开头,但如果缺少正斜杠则会添加它。