【问题标题】:Good DRY approach to rendering and AJAX updating of page良好的 DRY 方法来渲染和 AJAX 更新页面
【发布时间】:2011-07-06 12:38:48
【问题描述】:

想象一个评论网站,用户可以在其中输入评分和可选的简短 cmets。

在每个评论页面上,您都有许多 cmets - 它们显示在页面末尾的表格中(顺便说一句 - 不是在寻找数据网格类型的控件,这太简单了)

我想让用户在不刷新页面的情况下输入新评论并更新页面。(到目前为止都是简单的东西,这不是问题)

什么是为页面生成的好方法。一些想法:-

  1. 在服务器端生成评论 HTML,使用 javascript 客户端附加新评论。缺点是您在两个地方有表格 HTML 生成代码。 优势 - 就搜索引擎而言,页面上有更多内容。

  2. 服务器端仅将评论输出为 json/xml/whatever 并使用 javasript 在页面加载时动态呈现 HTML。

    缺点 - javascript 中的“模板”,设计师难以自定义 + 页面上缺少“内容”。

  3. 是否有一种方法可以将这两种方法结合起来 - 即一个模板框架,它将呈现现有的数据服务器端,但也发送模板片段客户端,以便在那里可以重用它进行添加/编辑。

  4. 使用 (2) 来获取初始页面加载时的数据您会

    • a) 在初始页面中包含 json/xml 并在页面加载时运行客户端渲染

    • b) 在页面加载时通过单独的 AJAX 调用获取它(+ 更简单,- 额外的请求和延迟)

我专注于 jQuery/Django,但这个问题适用于其他框架和 AJAX 库。

这个问题有点主观,希望不要越界!想法?

【问题讨论】:

  • 使用框架,(3)的一种方法是使用“部分”视图来呈现评论。服务器端代码循环通过现有评论并调用部分以一个接一个地呈现它们,作为呈现父页面的一部分;添加新评论时,javascript 会要求服务器呈现该新评论的部分内容并将其返回给客户端,并将其附加到页面上的现有评论中。
  • Matt - 我喜欢这个想法,并将进一步调查 - 如果你愿意,可以将其作为答案加入,确保获得积分和奖品 ;)

标签: jquery ajax


【解决方案1】:

使用框架,您的场景 (3) 的一种方法(结合两种方法)是使用“部分”视图。部分是可以自己渲染的视图片段;一个视图可以由多个部分组成。

在您的情况下,您需要定义一个部分来呈现评论。从头开始显示页面时,服务器端代码循环通过现有评论并调用部分以一个接一个地呈现它们。当新评论添加到现有页面时,javascript 要求服务器呈现该新评论的部分内容并将其作为 Ajax 响应返回,然后将其附加到现有评论中页面。

【讨论】:

    【解决方案2】:

    您不必提前知道模板,您只需在代码中设置挂钩,以便在渲染模板时使用 JSON 填充哪些数据。

    场景会这样工作:

    1. 服务器端在初始加载时生成页面
    2. AJAX 调用找到新的页面数据并想要呈现它
    3. jQuery 从页面中克隆评论项并使用 JSON 重新填充数据

    我个人喜欢在服务器端保持初始页面加载,以便更轻松地缓存页面,然后仅在需要更新页面或切换到相关页面而无需重新加载网站时使用 AJAX。

    给你一个例子:

    <ul class="commentsArea">
        <li class="comment" data-commenter-id="user1234">
            <a href="#" class="userName">Rob</a>
            <p class="userCommentContent">Some comment content would go here.</p>
        </li>
    </ul>
    

    然后你就有了一个模板函数:

    function template(comment, newCommentMetaData) {
        // comment is a cloned comment object
        // newCommentMetaData is the AJAX data
        comment.attr('data-commenter-id', newCommentMetaData.userid);
        comment.find('.userName').text(newCommentMetaData.name); 
        comment.find('.userCommentContent').text(newCommentMetaData.content); 
        return comment; 
    }
    

    最后你必须克隆评论以添加新评论:

    var newComment = $('li.comment:first').clone();
    // fill in your AJAX data here
    var newCommentMetaData = {
        userid: 'user2345',
        name: 'Pete',
        content: 'The new comment content goes here'
    };
    /* you would have to put an each() function here to iterate through all new comments
       and template them up, but hopefully you get the idea */
    
    template(newComment, newCommentMetaData).appendTo('.commentsArea').fadeIn();
    

    【讨论】:

    • 喜欢它 - 如果 html 元素的类名与返回的 json/xml 中的类名相同(我猜需要一些前缀),那么 javascript 会自动填充新元素(函数模板会只是一个将 json 元素与 html 元素匹配的循环)
    【解决方案3】:

    我在尝试建立一个可在线编辑的数据库以记录需要筹款团队联系的公司时遇到了类似的问题。

    最终我选择了 2-json 和 4-b,以减少传输的数据量,但由于 DRY+缺乏时间,我没有费心让它在没有 javascript 的情况下工作。没有内容供 SE 索引,但并不在意,因为它无论如何都是私有的。

    但是,如果每次更新传输整个表一次不是问题,我会选择 1。关于那个顺便说一句,我不明白你为什么说 HTML 生成代码会在两个地方。

    假设您有一个仅生成表格的 page_content 视图,您可以 1) 将其作为“组件”包含(因为它类似于 Nagare Framework 中的组件概念,其中页面是嵌套组件的树)渲染初始页面的视图(所有服务器端)然后2)使用ajax请求它并替换旧表的父表的innerHTML,这意味着HTML表生成代码仅在page_content中找到,并且搜索引擎很高兴。

    对 1 的一个很好的优化是不时轮询服务器以获取更新,但提供上次更新的时间戳,以便如果您已经拥有最新内容,服务器可能会发送空响应。 (好吧,前提是您不使用 HTML5 中的 WebSockets,这样就无需使用推送通知进行轮询)。

    2 本身对于一般用途来说很难看,三个听起来确实不错,但我不知道有任何模板框架可以在服务器端和客户端自动处理这些数据。

    对于编辑,尤其是添加,你是对的,如果你真的想发送尽可能少的数据,你必须在客户端有模板来制作(这就是我在我的页面上所做的编辑),但您可以通过将编辑/新项目发送到服务器然后使用 ajax 请求更新页面来更轻松地坚持使用 1。

    【讨论】:

    • re “不明白你为什么这么说” - 我的意思是,如果你为现有记录服务器端生成 html,但新建/编辑客户端,那么你的服务器端 python/php/whatever 和您的客户端 javascript 必须“知道”如何生成 HTML。想要改变,你必须在两个地方做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 2021-07-19
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多