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

时间:2013-10-07 05:40:27

标签: jquery jquery-mobile backbone.js backbone-views backbone-routing

我正在使用Backbone,require和jQuery mobile作为技术堆栈构建HTML5移动应用程序。通过与后端Web服务的连接等,应用程序非常流畅。 要在页面之间切换,我使用jQuery changePage。 要实现Backbone视图,我使用以下策略:

$( document ).delegate("#card-delivery-address", "pageshow", function(){
    require(["js/views/cardDeliveryAddressViews.js" ], function(cardDeliveryAddressViews) {
        new cardDeliveryAddressViews();
    });
});
  1. $ .mobile.changePage('deliveryAddress.html')=>改变现状 页面使用jquery mobile

  2. #card-delivery-address 上触发名为“ pageshow ”的事件时     (这意味着我的页面已成功插入DOM中     渲染)=>创建骨干视图并将$ el绑定到     现有的DOM并使用骨干控制DOM事件     视图。

  3. 要在视图之间传递数据和实例,我们使用window.tempData 全局变量,我们在其中放置上下文数据以便新建 视图会知道该怎么做。
  4. 单向导航成功,假设我来自view1 - > view2(带有tempData)然后来自view2 - >视图3(覆盖相同的tempData)。现在,这是我的问题:如果我们想从视图3返回 - >在视图2中,我们将需要用于初始化和渲染视图的tmpData内容2.当我们想要返回view1时也是如此。

    注意:我没有使用骨干路由器,但如果可以解决我的问题,我可以改用它。

    任何想法的人?

5 个答案:

答案 0 :(得分:2)

在页面转换期间,将从DOM中删除上一页

要保留DOM中所有以前访问过的网页,您可以添加以下属性:

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

或初始化全局参数:

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

答案 1 :(得分:2)

好的,让我们再试一次。我们将实现一个由页面路径键入的数据存储。

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"

现在,您的所有页面都有一个“本地”数据存储区,允许它们在整个导航过程中保存状态/数据。

注意:如果您不使用pushState,则必须使用window.location.hash代替window.location.pathname作为PagesData中的键。

答案 2 :(得分:1)

为什么不将windows.tempData作为对象?

windows.tempData = {};

存储页面数据:

window.tempData["id_of_page"] = your_data;

pagebeforeshow

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

答案 3 :(得分:1)

使用堆栈可以解决您的问题。浏览器的内部历史记录处理使用它来处理导航和后退按钮。

使用Array及其push()pop()方法在Javascript中实现堆栈。它们允许您保存和恢复以前的状态。

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();
...

当然,如果您从view3导航到view2,如果类似于“后退”操作,则此方法有效。如果故意导航到之前已初始化的任何页面,则必须将页面状态保存在哈希中,并按页面名称(或完整路径)索引。

您的案例应符合这两种模式中的一种。如果没有,要么你的要求没有明确定义,要么我误解了你的问题。

答案 4 :(得分:1)

thibauts' answer似乎正朝着正确的方向发展。请给它一个阅读。

我理解你的问题的方式。在任何时候打开“page3a”取决于前一页。如果它是“page2a”它将以某种方式工作。如果它是“page2b”它将以不同的方式工作。这些信息保存在每个页面的tempData中。

骨干路由无法解决此问题。因为它们只提供将URL路由转换为执行序列的方法。您仍然需要管理tempData。 最终的解决方案取决于tempData的大小以及如何管理它。是否有一些共享数据可以从tempData结构中取出并保存在共享结构中。是否有一些数据可以单独保存,变化非常少,可以实现某种memento pattern

有三种情况 -

  1. tempData相对较小,您可以保留一些副本 - 在这种情况下,您可以在circular buffer中保留tempData的固定历史[比如说最后10页]。继续删除最旧的项目,并在每次访问时添加新项目。如果用户没有更改任何内容并专门尝试前进按钮/导航,这将为您提供后退导航,如thibauts所述和历史记录跳转以及后退导航后的导航。

      

    1.1 编辑:如果您希望保留已经备份的转发操作,您仍然可以将其保留在循环队列中,   但是这样你就必须区分view2的两次访问   (看评论)。并将一切都视为前进和推进   历史(循环队列)。另一种方法是保持指针(数组   指数。如果可以,请参考缓冲区中的当前页面   当添加新页面(在某些动作上)缓冲移动指针时   那个。当做后退/前进动作时,只需移动点   缓冲和渲染。 [如果实施起来太复杂或太昂贵,那么   用户从中移回后,可以完全忽略视图/页面。   只需将其从历史记录中删除,以便用户无法再次使用fwd。或者回来   在回到新的后退后两次到达它。 backbone.router有办法   历史取代]

  2. tempData很大足以让你只保留少量副本[假设小于5]。在这种情况下,请保留上一页的一个副本。并保留历史记录中特定关键页面的副本,用户返回的可能性很高。例如,在购物流程中,用户可以比地址页面更频繁地返回购物车。您将需要一个特殊的数据结构,您可以在其中保持每个页面的优先级。优先级取决于时间和一些偏差标准。最新获得高时间参数,最重要的是获得高偏置参数。每当您访问新页面时。删除优先级最低的tempData。

  3. tempData具有可怕的大小 - 放弃后退导航。保留历史记录中的几个点,如重置点(如果可能),以及从头开始重新创建tempData的位置。

  4. 如果还有其他瓶颈而不是tempData。请评论。