【问题标题】:Ajax state history in coldfusion pageColdfusion页面中的Ajax状态历史
【发布时间】:2012-01-13 15:51:14
【问题描述】:

我很困惑如何做到这一点。我有一个页面,它有一个弹出过滤器,它有一些输入元素和一个“应用”按钮(不是提交)。单击该按钮时,将进行两次 jquery .get() 调用,将图形、DataTables 网格、照片和其他信息加载到四个单独的选项卡中。在图表内部,如果单击特定元素,用户将被带到另一个页面,在该页面中数据被向下钻取到更精细的级别。这一切都很好。

问题是如果用户决定返回原始页面,但使用 ajax 生成的图形/网格/照片等。最初我认为我会存储一个会话变量,其中包含用于形成原始查询的过滤器变量,并且在返回页面时,如果找到会话变量,则将再次进行原始 ajax 调用,重新填充选项卡。

我发现这种方法的问题是,当使用浏览器的后退按钮返回页面时,Coldfusion 无法识别会话变量已设置。如果我在原始页面和第二页都转储会话 var,我可以在第二页看到新设置的 var,如果我通过导航菜单转到原始页面,我可以看到它,但如果我使用后退按钮。

SO.... 从这里阅读关于 ajax 浏览器历史插件的帖子,似乎有各种 jquery 插件可以帮助解决这个问题,包括 BBQ。我看到这种方法的问题是它需要使用锚元素来触发它,然后使用锚的 href 属性修改查询字符串。我想我可以修改页面以包含一个隐藏的锚点。

我的问题终于是:像 BBQ 这样的 ajax 历史插件是实现这一点的最佳方式,还是有办法让 Coldfusion 在通过后退按钮返回页面时看到新创建的会话变量?或者,我是否应该考虑重新构建页面,以便将 ajax 调用替换为返回页面的表单提交?

一如既往地提前致谢。

编辑:一些有助于澄清事情的代码: 这是进行原始 ajax 调用的按钮:

<button id="applyFilter">APPLY</button> 

以及在#applyFilter上调用的部分js,包裹在$(document).ready()中:

$('#applyFilter').click(function(){
    // fill in the Photos tab
        $.get('tracking/listPhotos.cfm',
            {
                id: id,
                randParam: Math.random()
            },
            function(response){
                $('#tabs-photos').html(response);
            }
        );
    });

最后,当用户在 ajax 生成的图表上调用向下钻取时,它会使用已填充所需变量的 MaintAction 表单:

function DrillDown() {
    //get the necessary variables and populate the form inputs
    document.MaintAction.action = "index.cfm?file=somepage.cfm&Config=someConfig";
    document.MaintAction.submit();
}

这会将我们带到新页面,我们希望从该页面返回到第一页,但其中包含 ajax 加载的照片。

【问题讨论】:

    标签: ajax caching jquery coldfusion


    【解决方案1】:

    最好的办法是使用烧烤方法。为此,您不必在页面中实际包含锚标记;事实上,这样做会导致问题。本页:http://ajaxpatterns.org/Unique_URLs 解释了底层流程是如何工作的。我确信一个 jQuery 插件会让实际的实现变得更加容易。

    关于您的其他问题,关于如何使用会话变量来完成 - 在学习 BBQ 方法之前,我实际上已经做过类似的事情。这专门用于保存 jqGrid 组件的状态,但可以轻松更改以支持任何特定的 Ajax 状态。基本上,我所做的是为每个组件的每个实例保留一个会话变量,这些实例存储了通过 AJAX 请求传递给服务器的最后一个参数。然后,在客户端,我做的第一件事是向服务器运行一个同步 XHR 请求,以从该会话变量中获取状态。使用该同步请求的回调方法,然后我使用这些保存的参数在我的页面上设置组件。这对我有用,但如果我必须再做一次,我肯定会使用 BBQ 方法,因为它处理起来更简单,并且允许不止一个级别的历史记录。

    一些基于您的更新的示例代码:

    $('#applyFilter').click(function(){
    
        var id = $("#filterid").val(); // assumes the below id value is stored in some input on the page with the id "filterid"
        // fill in the Photos tab
            $.get('tracking/listPhotos.cfm',
                {
                    id: id // I'm assuming this is what you need to remember when the page is returned to via a back-button...
                    //randParam: Math.random() - I assume this is to prevent caching?  See below
                },
                function(response){
                    $('#tabs-photos').html(response);
                }
            );
        });
    
    
    /* fixes stupid caching behavior, primarily in IE */
    $.ajaxSetup({ cache: false });
    
    
    $.ajax({
       async: false,
       url: 'tracking/listPhotosSessionKeeper.cfm',
       success: function (data, textStatus, XMLHttpRequest)
       {
          if (data.length)
          {
             $("#filterid").val(data);
             $('#applyFilter').trigger('click');
          }
       }
    });
    

    这是您在客户端获取照片列表状态所需的。在服务器端,您需要将此修改添加到 tracking/listPhotos.cfm:

    <cfset session.lastUsedPhotoFilterID = URL.id>
    

    并添加这个新的一行文件,tracking/listPhotosSessionKeeper.cfm:

    <cfif IsDefined("session.lastUsedPhotoFilterID")><cfoutput>#session.lastUsedPhotoFilterID#</cfoutput></cfif>
    

    这些更改将一起跟踪用户使用的最后一个 ID,并在每次呈现页面时加载它(无论是通过后退按钮,还是仅通过用户重新访问页面)。

    【讨论】:

    • 如果您提供一些代码,我可以向您展示如何实现我描述的会话+同步 XHR 方法。
    • 非常感谢!您需要多少代码 - 只是 ajax 调用?
    • 我想说,如果您编辑了原始问题并为您的 AJAX 组件之一添加了一些 CFML 并为其添加了相关的 JS,那应该足够了。
    • 再次感谢您的帮助。我正在整理中。
    猜你喜欢
    • 1970-01-01
    • 2015-07-20
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-27
    相关资源
    最近更新 更多