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 - это идентификатор нового элемента, хранящегося в БД)

712   8  

8 ответов:

просто вы можете использовать $state.transitionTo вместо $state.go . $state.go звонки $state.transitionTo внутренне, но автоматически устанавливает параметры в { location: true, inherit: true, relative: $state.$current, notify: true } . Вы можете позвонить $state.transitionTo и set notify: 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

    Ничего не найдено.