Магистральный маршрутизатор получает длину истории для кнопки «Назад»

Я использую Backbone внутри приложения PhoneGap. Как и каждому мобильному приложению, мне нужна функциональность кнопки «Назад». По сути, он отлично работает с Backbone, потому что я могу просто использовать window.history.back(), и он просто работает.

Единственная проблема, с которой я столкнулся, — это решить, когда отображать кнопку «Назад». Использование window.history.length не работает, потому что оно не уменьшается при использовании back() (конечно, потому что вы можете использовать и forward()).

Есть ли способ определить, есть ли еще история или я уже в нижней части стека? Поскольку браузер, похоже, не предоставляет эту информацию (Как проверить, может ли пользователь вернуться в историю браузера или нет), возможно, Backbone отслеживает это?


person Prinzhorn    schedule 30.01.2013    source источник


Ответы (3)


Вы можете реализовать что-то подобное довольно легко

Backbone.history.length = 0;
Backbone.history.on('route', function () { ++this.length; });
myRouter.back = function () {
  Backbone.history.length -= 2;
  window.history.back();
};

И просто используйте myRouter.back(), чтобы вернуться.

person Casey Foster    schedule 30.01.2013
comment
Я тоже так делаю, и это работает, пока вы можете управлять обратной навигацией. Я не работаю, если пользователь может перемещаться назад с помощью встроенной кнопки «Назад» в браузере или аппаратной кнопки телефона. - person jevakallio; 30.01.2013
comment
@ casey-foster Одна проблема: при использовании {replace:true, trigger: true} вы облажались - person Prinzhorn; 30.01.2013
comment
Я использовал это решение, чтобы определить, был ли маршрут новым сеансом/вкладкой браузера или нет. if (length) { /*сеанс существующей вкладки браузера*/ } else { /* новый сеанс вкладки браузера */ } - person Ken; 03.06.2015

Ответ Кейси Фостера выглядит красиво на первый взгляд, но имеет недостаток: при использовании router.navigate с trigger и replace, для которых установлено значение true, вы получите неправильный счетчик.

Я придумал гораздо более простое решение: в основном есть только один маршрут, где мне не нужна кнопка «Назад», и это маршрут index. Таким образом, мой код теперь выглядит так

Backbone.history.on('route', _.bind(function(router, route) {
    if(route === 'index') {
        this.$el.removeClass('has-back-button');
    } else {
        this.$el.addClass('has-back-button');
    }
}, this));
person Prinzhorn    schedule 30.01.2013
comment
index -› another page -› index, вы не можете вернуться к another page через window.history.back(), верно? - person Casey Foster; 30.01.2013
comment
Вы можете перейти к index только с помощью кнопки «Назад». Индекс содержит список. Вы открываете элемент (и, возможно, подэлементы) и используете кнопку «Назад», чтобы вернуться к списку. Так что это отлично работает для моего варианта использования. - person Prinzhorn; 30.01.2013
comment
Эй, если это удовлетворяет ваш вариант использования, тогда это все, что вам нужно. Совет: если вы используете BB ›= 0.9.9, вы можете написать this.listenTo(Backbone.history, 'route', function (__, route) { ... }); без необходимости _.bind функции. Это также упрощает очистку событий (и автоматическую в View#remove) с помощью this.stopListening(). - person Casey Foster; 30.01.2013
comment
@CaseyFoster Спасибо, я почти забыл о listenTo (однажды наткнулся на него). - person Prinzhorn; 30.01.2013

Основываясь на @CaseyFoster answer, вы можете следите за историей сами. Помимо собственной кнопки «Назад» вам нужно отловить аппаратное нажатие кнопки «Назад» устройства.

PhoneGap предоставляет для этого событие backbutton:

document.addEventListener("backbutton", function() {
  Backbone.history.length -=2;
}, false);

Обратите внимание, что Backbone.history.length определено в ответе Кейси Фостера, оно не является частью самой Backbone.

person jevakallio    schedule 30.01.2013