How to keep a clean browser history in a backbone.js app?

删除回忆录丶 提交于 2019-12-30 06:09:42

问题


My backbone.js has three views:

  1. List of categories
  2. List of items in category
  3. Form for individual item

I'm using backbone.js router to navigate between these views. The user flows in the app go 1<-->2, 2<-->3 and 3 --> 1. The user can navigate back and forth using browser back and forward buttons, which is wanted behavior. Deep linking to any item works also.

The problem is that I want to keep the history clean. Here's an example usage flow:

  • User opens list of categories. History: "Category list" (correct)
  • User select "My category". History: "My category" < "Category list" (correct)
  • User select "My item". History: "My item" < "My category" < "Category list" (correct)
  • User fills form and saves, is redirected to "Category list". History: "Category list" < "My item" < "My category" < "Category list" ( should be just "Category list" )

Another example:

  • User opens url of "My category"
  • User presses home button. History: "Category list" < "My category", should be "Category list"

Any ideas on how to implement this in a clean way?


回答1:


There is no way to implement the first example that you provided. You cannot implement the first example because there is no way to "delete" the browser history using Javascript.

There is no way to clear the session history or to disable the back/forward navigation from unprivileged code. The closest available solution is the location.replace() method, which replaces the current item of the session history with the provided URL.

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

At best you can prevent the current page from being added to the browser history by using window.location.replace or window.history.replaceState. Backbone.js provides a convenient way of doing this by calling router.navigate(fragment, [options]) on your router object and specifying {replace: true} in the options.

Instead of relying on different routes to determine which view to display, I would try instead writing a master view which could handle showing/hiding the specific views.

EDIT

Ok, entering hacky territory...

Since it seems that the "Category List" page is the page where history should be "reset", the solution I have posted attempts to solve both use cases you have mentioned. The code keeps track of a historyState variable, which represents when the "category-list" page is visitied as well as the other pages visited after it.

// 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++;
        }
    });
});
  • If historyState is -1 - we have not yet visited the "category-list" page.
  • If historyState is 0 - we are currently on the "category-list" page.
  • If historyState is greater 0 - number of pages visited since viewed "category-list" page.

Now anytime a link is used to navigate to the "category-list" page, make sure it calls the following method to handle the appropriate navigation.

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});  
  } 
}

If the 'category-list' page has already been visited go back in history the appropriate number of entries (this unfortunately keeps the other pages in the history, so you can still go forward to them). Otherwise if the 'category-list' page hasn't been visited yet navigate to it and be sure not to add the current page to the history.




回答2:


There is no way to delete history from backbone history, you can re-route the navigation by adding some logic by getting current fragment

or you can use history.js (Works on most of the browser)

while https://developer.mozilla.org/en/DOM/window.history is only for Mozila firefox so this does not work for android app



来源:https://stackoverflow.com/questions/9906648/how-to-keep-a-clean-browser-history-in-a-backbone-js-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!