Как сохранить чистую историю браузера в приложении backbone.js?

My backbone.js имеет три вида:

  • Список категорий
  • Список элементов в категории
  • Форма для отдельного элемента

Я использую backbone.js router для перемещения между этими представлениями. Пользователь в потоке приложения добавляет 1 ↔ 2, 2 ↔ 3 и 3 → 1. Пользователь может перемещаться взад и вперед с помощью кнопок браузера и вперед, что является желаемым поведением. Также работает глубокая привязка к любому элементу.

Проблема в том, что я хочу сохранить историю чистой. Вот пример потока использования:

  • Пользователь открывает список категорий. История: "Список категорий" (правильный)
  • Пользователь выбирает "Моя категория" . История: "Моя категория" < "Список категорий" (правильный)
  • Пользователь выбирает "Мой элемент" . История: "Мой элемент" < "Моя категория" < "Список категорий" (правильный)
  • Пользователь заполняет форму и сохраняет ее, перенаправляется в "Список категорий" . История: "Список категорий" < "Мой элемент" < "Моя категория" < "Список категорий" (должен быть просто "Список категорий" )

Другой пример:

  • Пользователь открывает URL-адрес раздела "Моя категория"
  • Пользователь нажимает кнопку "домой". История: "Список категорий" < "Моя категория" должна быть "Список категорий"

Любые идеи о том, как реализовать это чистым способом?

Ответ 1

Невозможно реализовать первый пример, который вы предоставили. Вы не можете реализовать первый пример, потому что нет возможности "удалить" историю браузера с помощью Javascript.

Невозможно очистить историю сеанса или отключить навигацию назад/вперед от непривилегированного кода. Наиболее доступным решением является метод location.replace(), который заменяет текущий элемент истории сеанса указанным URL.

- https://developer.mozilla.org/en/DOM/window.history

В лучшем случае вы можете запретить добавление текущей страницы в историю браузера с помощью window.location.replace или window.history.replaceState. Backbone.js обеспечивает удобный способ сделать это, вызвав router.navigate(fragment, [options]) на свой объект маршрутизатора и указав {replace: true} в параметрах.

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

ИЗМЕНИТЬ

Хорошо, входя в хакерскую территорию...

Так как кажется, что страница "Список категорий" - это страница, где история должна быть "reset", решение, которое я опубликовал, пытается решить оба варианта использования, о которых вы упоминали. Код отслеживает переменную historyState, которая отображается, когда посещается страница "Список категорий" , а также другие страницы, посещенные после нее.

// in your application init...
$(function(){
    window.historyState = -1;
    router = new Backbone.Router({ 
        routes: {
            "category-list": category-list,
            "category": category,
            "item": item
        }

        category-list: function(){
            historyState = 0;
        },

        category: function(){
            if(historyState >= 0)
                historyState++;
        },

        item: function(){
            if(historyState >= 0)
                historyState++;
        }
    });
});
  • Если historyState - -1 - мы еще не посетили страницу "Список категорий" .
  • Если historyState - 0 - мы в настоящее время находимся на странице "Список категорий" .
  • Если historyState больше 0 - количество посещенных страниц с момента просмотра страницы категории.

Теперь, когда ссылка используется для перехода на страницу "Список категорий" , убедитесь, что она вызывает следующий метод для обработки соответствующей навигации.

function routeToCategoryList(){
  if( historyState > 0 ){ 
    // 'category-list' already exists in our history route to that page.
    window.history.go((historyState * -1));
  } else {  
    // otherwise, don't store an entry for the current page we are on.
    router.navigate("/category-list", {trigger: true, replace: true});  
  } 
}

Если страница "Список категорий" уже была посещена, верните в историю соответствующее количество записей (это, к сожалению, сохраняет другие страницы в истории, поэтому вы все равно можете перейти к ним). В противном случае, если страница "Список категорий" еще не была посещена, перейдите к ней и не добавьте текущую страницу в историю.

Ответ 2

Нет способа удалить историю из истории магистрали, вы можете перенаправить навигацию, добавив некоторую логику, получив текущий фрагмент

или вы можете использовать history.js(работает в большинстве браузеров)

пока https://developer.mozilla.org/en/DOM/window.history предназначен только для Mozilla firefox, поэтому это не работает для приложения Android.