Подтвердить что ты не робот

Переадресация AngularJS без нажатия состояния истории

Я работаю над приложением AngularJS, у которого есть весь маршрут (например, .when('/:slug', {...)), который необходим для поддержки устаревших форматов url из предыдущей (не angular) версии приложения. Контроллер, который реагирует на catch, пытается потянуть связанный объект и, если не найден, перенаправляет на страницу 404 с помощью метода $location.path. Это работает при получении пользователя на странице 404, но когда пользователь возвращается в свой браузер, он возвращает их на страницу, которая вынуждала их на страницу 404 в первую очередь, и они в конечном итоге не могут выйти из цикла.

Мой вопрос в том, есть ли 1) лучший шаблон для обработки этой ситуации или 2) если есть способ перенаправить пользователя, который не заставляет состояние истории в браузере?

4b9b3361

Ответ 1

Вы можете изменить URL-адрес без добавления в состояние истории, найти здесь в разделе "Метод замены". Это фактически то же самое, что вызывать HTML5 history.replaceState().

$location.path('/someNewPath').replace();

Я не нашел, что можно изменить представление без изменения URL-адреса. Единственный способ изменить вид, который я нашел, - это изменить путь к местоположению.

Ответ 2

Нормальная работа системы маршрутов предназначена для службы $route наблюдать за событием $locationChangeSuccess, а затем начать загрузку маршрута. После загрузки шаблона, выполнения шагов решения и создания экземпляра контроллера он, в свою очередь, транслирует событие $routeChangeSuccess. Этот $routeChangeSuccess контролируется директивой ng-view и как он знает, чтобы менять шаблоны и области действия после того, как новый маршрут готов.

При всем сказанном выше может работать код приложения, который эмулирует поведение службы $route, обновляя текущий маршрут и выдавая событие изменения маршрута, чтобы обновить представление:

var errorRoute = $route.routes[null]; // assuming the "otherwise" route is the 404
// a route instance is an object that inherits from the route and adds
// new properties representing the routeParams and locals.
var errorRouteInstance = angular.inherit(
    errorRoute,
    {
        params: {},
        pathParams: {},
    }
);
// The $route service depends on this being set so it can recover the route
// for a given route instance.
errorRouteInstance.$$route = errorRoute;

var last = $route.current;
$route.current = errorRouteInstance;

// the ng-view code doesn't actually care about the parameters here,
// since it goes straight to $route.current, but we should include
// them anyway since other code might be listening for this event
// and depending on these params to behave as documented.
$rootScope.broadcast('$routeChangeSuccess', errorRoute, last);

Вышеизложенное предполагает, что ваш маршрут "по-другому" не имеет шагов "разрешения". Он также предполагает, что он не ожидает никаких $routeParams, что, конечно, верно для маршрута "иначе", но может быть неверным, если вы используете другой маршрут.

Непонятно, что из вышеперечисленного зависит от деталей реализации и интерфейса. Событие $routeChangeSuccess, безусловно, задокументировано, но свойство $$route экземпляра маршрута, по-видимому, представляет собой деталь реализации системы маршрута, учитывая его двузначный знак. Деталь, что маршрут "в противном случае" хранится в таблице маршрутов с ключом null, возможно, также является деталью реализации. Таким образом, при всем этом сказано, что это поведение не может оставаться функциональным в будущих версиях AngularJS.

Для получения дополнительной информации вы можете обратиться к коду ng-view, который обрабатывает это событие, что в конечном итоге означает, что приведенный выше код пытается удовлетворить, а также код, испускающий события, который я использовал в качестве основы для приведенного выше примера. Как вы могли бы сделать вывод из этих ссылок, информация в этом сообщении получена из последней ведущей ветки AngularJS, которая на момент написания помечена как 1.2.0-моментальный снимок.