AngularJS UI Router-изменить url без перезагрузки состояния
в настоящее время наш проект использует default $routeProvider, и я использую этот "хак", чтобы изменить 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
после clicking при сохранении я показываю success-alert и я хочу изменить маршрут /category/new до /caterogy/23 (23 - это идентификатор нового элемента, хранящегося в БД)
8 ответов:
просто вы можете использовать
$state.transitionToвместо$state.go.$state.goзвонки$state.transitionToвнутренне, но автоматически устанавливает параметры в{ location: true, inherit: true, relative: $state.$current, notify: true }. Вы можете позвонить$state.transitionToи setnotify: false. Например:$state.go('.detail', {id: newId})можно заменить на
$state.transitionTo('.detail', {id: newId}, { location: true, inherit: true, relative: $state.$current, notify: false })Edit: как предложил fracz это может быть просто:
$state.go('.detail', {id: newId}, {notify: false})
ОК, решена :) Угловой UI маршрутизатор имеет этот новый метод, $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(); }]);Я думаю, что этот метод в настоящее время включены только в мастер версия углового маршрутизатора ui, тот, с дополнительными параметрами (которые тоже хороши, кстати). Он должен быть клонирован и построен из исходного кода с помощью
grunt buildдокументы также доступны из источника, через
grunt ngdocs(они встроены в каталог / site) / / дополнительная информация в README.MD
кажется, есть другой способ сделать это, с помощью динамических параметров (который я не использовал). Много кредитов натеабеле.
к слову, вот дополнительные параметры в $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
проведя много времени с этой проблемой, вот что я получил работу
$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 });
эта установка решила следующие проблемы для меня:
- контроллер обучения не вызывается дважды при обновлении url из
.../до.../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 ... }
Если вам нужно только изменить url, но предотвратить изменение состояния:
изменить местоположение с помощью (add .заменить, если вы хотите заменить в истории):
this.$location.path([Your path]).replace();запретить перенаправление в ваше состояние:
$transitions.onBefore({}, function($transition$) { if ($transition$.$to().name === '[state name]') { return false; } });
Я сделал это, но давно в версии: v0. 2. 10 UI-router, как что-то вроде этого::
$stateProvider .state( 'home', { url: '/home', views: { '': { templateUrl: Url.resolveTemplateUrl('shared/partial/main.html'), controller: 'mainCtrl' }, } }) .state('home.login', { url: '/login', templateUrl: Url.resolveTemplateUrl('authentication/partial/login.html'), controller: 'authenticationCtrl' }) .state('home.logout', { url: '/logout/:state', controller: 'authenticationCtrl' }) .state('home.reservationChart', { url: '/reservations/?vw', views: { '': { templateUrl: Url.resolveTemplateUrl('reservationChart/partial/reservationChartContainer.html'), controller: 'reservationChartCtrl', reloadOnSearch: false }, '[email protected]': { templateUrl: Url.resolveTemplateUrl('voucher/partial/viewVoucherContainer.html'), controller: 'viewVoucherCtrl', reloadOnSearch: false }, '[email protected]': { templateUrl: Url.resolveTemplateUrl('voucher/partial/voucherContainer.html'), controller: 'voucherCtrl', reloadOnSearch: false } }, reloadOnSearch: false })
попробуйте что-то вроде этого
$state.go($state.$current.name, {... $state.params, 'key': newValue}, {notify: false})
Я не думаю, что вам нужен ui-маршрутизатор вообще для этого. Документация, доступная для $location service написано в первом абзаце "...изменения $location отражаются в адресной строке браузера."Он продолжает позже говорить:" что он не делает? Это не вызывает полной перезагрузки страницы при изменении URL-адреса браузера."
Итак, имея это в виду, почему бы просто не изменить $location.путь (как метод геттер и сеттер) с чем-то подобным следующее:
var newPath = IdFromService; $location.path(newPath);на документация отмечает, что путь всегда должен начинаться с косой черты, но это будет добавить его, если он отсутствует.
Comments