4

我正在使用 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 全局变量,我们将上下文数据放入其中,以便新视图知道该做什么。

以一种方式导航是成功的,假设我来自 view1 --> view2 (with tempData) 然后来自 view2 --> view 3 (覆盖相同的 tempData)。现在,这是我的问题:如果我们想从视图 3 返回 --> 视图 2,我们将需要用于初始化和渲染视图 2 的 tmpData 内容。当我们想返回视图 1 时也是如此.

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

有什么想法吗?

4

5 回答 5

2

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

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

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

或通过初始化全局参数:

$.mobile.page.prototype.options.domCache = true;
于 2013-10-09T06:54:12.190 回答
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 中的键。

于 2013-10-10T10:25:21.180 回答
1

为什么不做windows.tempData一个对象?

windows.tempData = {};

要存储页面数据:

window.tempData["id_of_page"] = your_data;

pagebeforeshow

myDataForThisPage = window.tempData[this.id];  // assuming "this" being your page element
于 2013-10-09T08:27:36.663 回答
1

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

堆栈是在 Javascript 中使用 an Arrayand itspush()pop()方法实现的。它们允许您保存和恢复以前的状态。

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 类似于“后退”操作,则此方法有效。如果它是故意导航到之前可能已初始化的任何页面,则您必须将页面的状态保存在哈希中,按页面名称(或完整路线)索引。

您的机箱应该适合这两种型号中的一种。如果没有,要么你的要求没有很好地定义,要么我误解了你的问题。

于 2013-10-09T12:53:37.860 回答
1

thibauts 的回答似乎是正确的方向。一定要读一读。

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

骨干路由无法解决这个问题。因为它们只是提供将 URL 路由转换为执行序列的方法。您仍然需要管理 tempData。最终的解决方案取决于 tempData 的大小以及您如何管理它。是否有一些共享数据可以从 tempData 结构中取出并保存在共享结构中。是否有一些数据可以自己保存,很少更改并且可以实现某种纪念品模式

有三种情况——

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

    1.1编辑:如果您希望保留已经支持的转发操作,您仍然可以将其保留在循环队列中,但这样您必须区分 view2 的两次访问(见注释)。并将一切视为向前移动并推动历史(循环队列)。另一种方法是在缓冲区中保留一个指向当前页面的指针(数组索引。如果可能的话,请参考),并在将新页面(在某些操作上)添加到缓冲区时移动该指针。进行后退/前进移动时,只需移动缓冲区中的点并渲染。[如果实施起来太复杂或成本太高,一旦用户移回视图/页面,您可以完全忽略它。只需将其从历史记录中删除,用户就不能再次使用 fwd。或在 back-new-back-back 之后返回两次以达到它。[backbone.router 有一种历史替换方式]

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

  3. tempData 的大小非常大- 放弃后面的导航。在历史记录中保留几个点,这些点类似于重置点(如果可能),并且您可以从头开始重新创建 tempData。

如果除了 tempData 之外还有其他瓶颈。请评论。

于 2013-10-10T06:12:57.623 回答