简体   繁体   English

Backbone和jqm:后退按钮如何恢复页面上下文

[英]Backbone and jqm: back button how to restore page context

I'm building an HTML5 mobile application using Backbone, require and jQuery mobile as a technology stack. 我正在使用Backbone,require和jQuery mobile作为技术堆栈构建HTML5移动应用程序。 The application is really smoothy with a connection to a backend web service and so on. 通过与后端Web服务的连接等,应用程序非常流畅。 To Change between the pages I use jQuery changePage. 要在页面之间切换,我使用jQuery changePage。 To instanciate Backbone views I use the following strategy: 要实现Backbone视图,我使用以下策略:

$( document ).delegate("#card-delivery-address", "pageshow", function(){
    require(["js/views/cardDeliveryAddressViews.js" ], function(cardDeliveryAddressViews) {
        new cardDeliveryAddressViews();
    });
});
  1. $.mobile.changePage('deliveryAddress.html') => changes the current page using jquery mobile $ .mobile.changePage('deliveryAddress.html')=>使用jquery mobile更改当前页面

  2. When an event called " pageshow " is fired on #card-delivery-address (which means that my page was inserted in the DOM and successfully rendered) => create the backbone view and bind the $el to an existing DOM and taking control on the DOM events using backbone views. #card-delivery-address触发一个名为“ pageshow ”的事件时(这意味着我的页面已插入DOM并成功呈现)=>创建骨干视图并将$ el绑定到现有DOM并控制使用主干视图的DOM事件。

  3. To pass data and instances between views we use a window.tempData global variable in which we put the context data so that the new view will know what to do. 要在视图之间传递数据和实例,我们使用window.tempData全局变量,我们在其中放置上下文数据,以便新视图知道该做什么。

Doing one way navigation is successful, suppose that I come from view1 --> view2 (with tempData) then from view2 --> view 3 (override the same tempData). 单向导航是成功的,假设我来自view1 - > view2(带有tempData),然后来自view2 - > view 3(覆盖相同的tempData)。 Now, and here is my problem: if we want to go back from view 3 --> view 2 we will need the tmpData content that we used to initialize and render the view 2. The same thing when we want to go back to view1. 现在,这是我的问题:如果我们想从视图3 - >视图2返回,我们将需要我们用于初始化和渲染视图的tmpData内容2.当我们想要返回view1时同样的事情。

Note: I'm not using backbone router but I can change to use it if that will solve my problem. 注意:我没有使用骨干路由器,但如果能解决我的问题,我可以改用它。

Any ideas guys? 有什么想法吗?

During the page transition previous page is going to be removed from the DOM 在页面转换期间,将从DOM中删除上一页

To keep all previously-visited pages in the DOM you can add the attribute: 要保留DOM中所有以前访问过的页面,您可以添加属性:

<div data-role="page" id="card-delivery-address" data-dom-cache="true">              
    <!-- [...] -->      
</div>

or by initializing global parameter: 或者通过初始化全局参数:

$.mobile.page.prototype.options.domCache = true;

Ok let's give it another try. 好的,让我们再试一次。 We'll implement a data store keyed by pages' path. 我们将实现一个由页面路径键入的数据存储。

var pagesData = {};

// Let's assume we just switched to page '/my/page/1'

// Get a reference to the stored page data if it exists, 
// or create it empty and return it.
var currentPageData = pagesData[window.location.pathname] ||  
                     (pagesData[window.location.pathname] = {});

currentPageData.foo = 'bar';

console.log(pagesData['/my/page/1'].foo); // > "bar"

Now all your pages have a "local" datastore that allows them to save their state/data throughout navigation. 现在,您的所有页面都有一个“本地”数据存储区,允许它们在整个导航过程中保存其状态/数据。

NB: If you don't use pushState, you have to use window.location.hash in place of window.location.pathname as a key in PagesData. 注意:如果不使用pushState,则必须使用window.location.hash代替window.location.pathname作为PagesData中的键。

Why not make windows.tempData an object? 为什么不让windows.tempData成为一个对象?

windows.tempData = {};

To store a page data: 存储页面数据:

window.tempData["id_of_page"] = your_data;

On pagebeforeshow : pagebeforeshow

myDataForThisPage = window.tempData[this.id];  // assuming "this" being your page element

Using a stack may solve your problem. 使用堆栈可以解决您的问题。 The internal history handling of your browser uses that to handle navigation and the back button. 浏览器的内部历史记录处理使用它来处理导航和后退按钮。

Stacks are implemented in Javascript using an Array and its push() and pop() methods. 堆栈是使用Array及其push()pop()方法在Javascript中实现的。 They allow you to save and restore a previous state. 它们允许您保存和恢复以前的状态。

var navigationStack = {...},
    currentState = {...};

...
// When going to a new page, you push (or save) the current state on the stack
navigationStack.push(currentState);
...

...
// When going back to the previous page you pop the previous state from the stack
currentState = navigationStack.pop();
...

Of course, this works if your navigation from view3 to view2 if akin to a "back" action. 当然,如果您从view3导航到view2,如果类似于“后退”操作,则此方法有效。 If it is a deliberate navigation to any page that may have been previously initialized, you are bound to save your pages' states in a hash, indexed by page name (or full route). 如果它是故意导航到任何可能先前已初始化的页面,则必须将页面状态保存在哈希中,按页面名称(或完整路径)索引。

Your case should fit one of these two models. 您的案例应该适合这两个模型中的一个。 If it doesn't, either your requirements are not well defined enought, or I misunderstood your question. 如果没有,或者您的要求没有明确定义,或者我误解了您的问题。

thibauts' answer seems in the right direction. thibauts的回答似乎正确的方向。 Do give that a read. 请给它一个阅读。

The way I understand your problem. 我理解你的问题的方式。 at any time opening a "page3a" depends on the previous page. 在任何时候打开“page3a”取决于前一页。 if it was "page2a" it will work in a certain way. 如果它是“page2a”它将以某种方式工作。 if it was "page2b" it will work differently. 如果它是“page2b”它将以不同的方式工作。 And this information you keep in tempData for every page. 这些信息保存在每个页面的tempData中。

This problem will not be solved by backbone routes. 骨干路由无法解决此问题。 As they just provides means of converting URL routes into a execution sequence. 因为它们只提供将URL路由转换为执行序列的方法。 You will still have to manage tempData. 您仍然需要管理tempData。 Solution in the end depends on the size of tempData and how you manage it. 最终的解决方案取决于tempData的大小以及如何管理它。 Is there some shared data which can be taken out of tempData structure and kept in a shared structure. 是否有一些共享数据可以从tempData结构中取出并保存在共享结构中。 Is there some data which can be kept on its own, changes very rarely and can implements some kind of memento pattern . 是否有一些数据可以自行保存,变化很少,可以实现某种纪念模式

there are three cases - 有三种情况 -

  1. tempData is relatively small and you can keep some copies of it - in this case you can keep fixed history [say last 10 pages] of tempData in a circular buffer . tempData相对较小 ,你可以保留它的一些副本 - 在这种情况下,你可以在循环缓冲区中保存tempData的固定历史[比如说最后10页]。 Keep on deleting oldest items and adding new one at every page visit. 继续删除最旧的项目,并在每次访问时添加新项目。 This will give you both back navigation as thibauts said and history jump along with forward navigation after back Navigation if the user haven't changed anything and specifically try forward button/nav. 如果用户没有改变任何东西并专门尝试前进按钮/导航,这将为thibauts提供返回导航和历史跳转以及返回导航后的前向导航。

    1.1 EDIT : In case you wish to retain a forward action which has already been backed, you can still keep it in the circular queue, but this way you have to distinguish between the two visits of view2 (see comments). 1.1 编辑 :如果您希望保留已经备份的转发操作,您仍然可以将其保留在循环队列中,但这样您必须区分view2的两次访问(请参阅注释)。 and consider everything as a forward move and push in history (circular queue). 并将一切视为前进和推进历史(循环队列)。 another way will be to keep a pointer (array index. reference if you may) to the current page in the buffer and when adding the new page (on some action) to buffer move the pointer the that one. 另一种方法是将指针(数组索引。引用,如果可能)保留到缓冲区中的当前页面,并在添加新页面时(在某些操作上)缓冲区移动指针。 when doing a back/forward moves just move the point in buffer and render. 当进行后退/前进移动时,只需移动缓冲区中的点并进行渲染即可。 [If it is too complex or costly to implement, you can completely ignore a view/page once user has moved back from it. [如果实现过于复杂或成本太高,一旦用户从中移回视图/页面,您就可以完全忽略它。 simply remove it from history so user cant use fwd again. 只需将其从历史记录中删除,以便用户无法再次使用fwd。 or back twice to reach it after back-new-back-back. 在返回后退后,或两次回到它。 backbone.router has a way of history replace] backbone.router有一种历史替代方式]

  2. tempData is large enough that you can keep only few copies of it [lets assume less than 5]. tempData足够 ,你只能保留它的几个副本[假设小于5]。 In this case keep one copy for the previous page. 在这种情况下,请保留上一页的一个副本。 and keep copies of specific key pages in history where there's high chance of user returning. 并保留历史记录中特定关键页面的副本,用户返回的可能性很高。 for example in a shopping flow, the user may return back to cart more often than the address page. 例如,在购物流程中,用户可以比地址页面更频繁地返回购物车。 You will need a special data structure for this, where you can maintain priority of every page. 您将需要一个特殊的数据结构,您可以在其中保持每个页面的优先级。 priority is based on the time and some biasing criteria. 优先级取决于时间和一些偏差标准。 the newest gets high time parameter and the most important gets high biasing parameter. 最新获得高时间参数,最重要的是获得高偏置参数。 whenever you visit a new page. 每当您访问新页面时。 remove the tempData of the lowest priority. 删除最低优先级的tempData。

  3. tempData is of monstrous size - give up on the back navigation. tempData具有可怕的大小 - 放弃后退导航。 keep few points in history which works like reset points (if possible) and where you can recreate the tempData from scratch. 保留历史记录中的几个点,如重置点(如果可能),以及从头开始重新创建tempData的位置。

If there's any other bottle neck than the tempData. 如果有任何其他瓶颈而不是tempData。 Please comment. 请评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM