繁体   English   中英

在页面数据准备好之前,如何延迟 jQuery Mobile 中的页面转换?

[英]How can I delay page transition in jQuery Mobile until page data is ready?

我有一个使用 jquery-mobile (jqm) 和淘汰赛构建的移动单页 Web 应用程序。 应用程序本身有多个页面,但它们都包含在一个 HTML 文档中。

问题:将我的“为页面创建视图模型”从同步行为更改为异步行为后,我遇到了 jquery-mobile 在数据准备好之前触发其事件的问题。

背景:直到最近我一直在处理示例数据,基本上是一个巨大的 JSON blob,一切都运行得很顺利。 使用来自各种来源的视图模型的新异步组合,数据不会立即准备好,我的“buildViewModel”方法采用连续回调而不是同步返回数据。

我订阅了 pagebeforecreate 和 pagebeforechange 事件,并在此处触发代码以填充视图模型。 问题在于,从事件处理程序返回后,jqm 在数据可用之前触发了剩余的事件链。 这导致页面转换到未准备好的页面,这是不希望的。

我曾尝试在所有事件之前调用event.preventDefault并在页面准备好进行 a) 增强和 b) 页面转换时手动调用 $.mobile.changePage,但没有任何运气。

我已经扫描了 jquery-mobile 源,但找不到任何看起来可以让我延迟pagebeforeshow事件的东西,这基本上是我能够正确呈现页面所需要的。

在 jquery-mobile 尝试增强页面和执行页面转换之前,如何确保 1) 数据可用和 2) 敲除已应用于执行初始 DOM 操作?

我还考虑使用同步 ajax 来获取资源,但这(我认为)不适用于从设备加载的资源(使用 PhoneGap/Cordova),并且还有其他我想避免的负面影响。

FWIW,我想避免通过在任何地方连接点击处理程序来手动处理所有导航事件,但如果需要,我对所有解决方案持开放态度。

如果这是重复的,请道歉; 我搜索并阅读了大量问题,但没有找到完全相同的答案或问题。 我会是第一个遇到这个问题的人,这听起来令人难以置信,因为我认为这是一个常见的场景。

更新:澄清了问题场景描述。

我有这个完全相同的问题。

我能想出的唯一解决方案是编写一个自定义转换处理程序,将转换开始推迟到 Ajax 请求完成。

这是展示该技术的小提琴 小提琴不使用淘汰赛,但确实展示了如何推迟过渡。

基本上,由于$.ajax()返回一个承诺,我可以将它导入默认转换处理程序返回的承诺,并从我的新处理程序返回它。

在我的 pagebeforeshow 处理程序中,我将 Ajax 承诺附加到页面,以便转换处理程序可以访问它。 不确定这是否是最好的方法,但我比使用全局变量更喜欢它。

我唯一不喜欢这个的地方是它延迟了转换的开始,直到 Ajax 响应到达,所以它可能感觉页面已经“挂”给用户,让他们再次点击。 手动显示加载消息使它感觉更灵敏。

希望这会有所帮助,如果您找到更好的解决方案,请告诉我!

在 jQuery Mobile 中面对动态内容时,延迟到新页面的转换直到其内容准备好是一个非常常见的问题。 解决这个问题最方便的方法是:

  • 不是经典的 href 类型导航,而是基于“点击”操作的链接,这些操作将首先检索内容,在 DOM 中构建一个新页面,然后通过$.mobile.changePage启动到这个新页面的$.mobile.changePage 这种方式的优点是容易到位,缺点是不用经典的href链接导航

  • 在文档级别绑定pagebeforechange事件以检测导航时目标页面是否是应包含动态内容的页面之一。 在这种情况下,您可以防止默认导航发生,花时间生成页面,并在成功时进行转换。 这在关于动态注入内容的 JQM 文档中进行了描述。 优点是您仍然可以依赖标准的href链接导航,但它需要更多的代码和上游设计才能正确检测页面导航并采取行动。

     $(document).on( "pagebeforechange", function( e, data ) { if ( typeof data.toPage === "string" ) { if ( data.toPage === "myDynamicPageName" ) { e.preventDefault(); //used to stop transition to the page (for now) /* Here you can make your ajax call In you callback, once you have generated the page you can call $.mobile.changePage (you can pass the Div of the new page instead of its name as the changepage parameter to avoid interrupting again the page change) */ } } });

将链接设置为调用“加载”函数而不是进行页面转换。 在您的加载函数中,显示“加载消息”并进行 JSON 调用。 最后,在JSON回调函数中,将page改为page2

负载函数:

function loadPage2() {
    /* show wait page */
    $.mobile.loading( 'show', {
            text: 'Loading massively huge dataset',
            textVisible: true
    });

     /* perform JSON call then call callback */
 }

回调函数

function callback() {
    $.mobile.changePage("#page2");
}

这是一个有效的 JSFiddle: http : //jsfiddle.net/8w7PM/

请注意,如果您不希望用户在等待时更新第 1 页中的输入字段,请在第 1 页和第 2 页之间引入“等待页面”,“等待页面”的初始化与“loadPage2”相同.

我认为你必须为所有你想要将数据从响应绑定到的小部件再次触发

例如,你将不得不调用triggercreaterefrest的元素事件$("#element").trigger('create'); JQuery Mobile 会将所有默认事件按原样绑定到元素

- - 编辑 - -

我刚刚创建了一个示例代码,我认为这与您的问题相同,请尝试链接http://jsfiddle.net/ndkhoiits/BneqW/embedded/result/

在渲染数据之前,我们必须调用服务来获取它们进行显示,这就是为什么所有由 jqm 绑定的事件将被删除的原因。

我有一个解决方法,不要让 jqm 在元素上触发任何东西,我们会在所有数据被knockoutjs 绑定后触发它让我们试试固定版本http://jsfiddle.net/ndkhoiits/c5a2b/embedded/result /

这是代码http://jsfiddle.net/ndkhoiits/c5a2b/

我有一个小型 jQuery Mobile/KnockoutJS 应用程序,并且遇到了同样的问题。 我的应用程序包含大约 5 页。 所有这些都包含在一个单独的物理 HTML 文档中,使用标准的<div data-role="page">标记分隔各个页面。

由于$.ajax成功,我终于使用了基于点击的导航并触发了$.mobile.changePage()

这种技术的缺点之一是,当依赖onclickhref属性时,您将失去按钮高亮显示。 请参阅我的相关帖子: href 与脚本化页面转换和按钮突出显示

我后来选择同时提供两者并依靠href来执行导航,同时使用onclick调用我的 JavaScript 逻辑来加载 ViewModels 等。我发现这是一个问题的唯一地方是在源上可能需要验证时页。 如果失败,则过渡已经开始,然后 UI 会闪回到源页面。 丑陋,但这仅发生在我的应用程序中的有限实例中。

我认为这些都不是特定于 Knockout 的。 我的确切解决方案可能会为您带来问题,因为您的导航可能会在您的模型完全加载之前完成,但如果您依赖$.mobile.changePage() ,它应该都可以工作并隐藏您的页面,直到它加载之后。 过渡应该可以正常工作。

<a href="#MyNewPage" data-bind="click:LoadNewPage" data-role="button">
    Load Page
</a>

$.ajax({
    url: url,
    cache: false,
    dataType: "json",
    data: requestData,
    type: "POST",
    async: true,
    timeout: 10000,
    success: function (data, textStatus, jqXHR) {
        // use either href or changePage but not both
        $.mobile.changePage("#NewPage");
    },
    error: function (jqXHR, textStatus, errorThrown) {
        alert("AJAX Error. Status: " + textStatus);
        // jqXHR.status
        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
    }
});

您应该将页面转换的代码放在 AJAX 调用的成功函数中。

$.ajax({
    url:"request-url",
    data: data,
    type: "POST",
    success: function(response){
        // Add Transition Code Here
    }  
});

暂无
暂无

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

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