【问题标题】:Render page initially and update via AJAX using the same template HTML最初渲染页面并使用相同的 HTML 模板通过 AJAX 进行更新
【发布时间】:2010-12-15 16:23:26
【问题描述】:

假设您有一个名为“View Story”的视图,它只是一个通过 Python/Django 在后端呈现的网页。在该页面上,底部有一个 cmets 列表,作为“查看故事”模板的一部分,使用 Django 的模板系统(在循环中)。此页面还允许您向列表添加评论。这是通过 AJAX 完成的,页面会使用新评论进行更新(无需发送新的整页请求)。

现在,在将新评论添加到列表末尾时,我希望为该新评论生成的 HTML(<li> 中的内容)使用与生成发送到的原始 cmets 完全相同的代码客户端通过原始请求。

有多种方法可以做到这一点:

  1. 让初始渲染将评论数据放入一个 javascript 变量中,并在渲染页面后通过 javascript 添加内容。然后,当添加新的 cmets 时,可以使用相同的 javascript 来呈现新的 cmets。问题:从搜索引擎的角度来看,如果它们是在页面呈现后生成的,我不确定谷歌是否能够索引 cmets - 我猜不是

  2. 每次通过 AJAX 添加新评论时,让 ajax 请求返回要放在页面上的实际 HTML,而不仅仅是新评论的 JSON 数据。可以使用用于呈现原始页面的相同模板 sn-p 生成 HTML。这样做的问题在于,它将 AJAX 请求与特定视图或我不喜欢的呈现方式联系在一起。

  3. 与 #2 类似,只是发出了单独的请求来检索新评论的 HTML,或者可能是所有 cmets,并且列表只是被擦除并重新呈现。不喜欢这样,因为它非常低效且不必要地耗时。

因此,总而言之,我想要一种方法来避免为单个视图重复模板/HTML 代码。而且我想就对其他人有效的方法提出一些建议,因为我很确定这是一个常见的情况,无论后端的技术如何。

谢谢!

【问题讨论】:

    标签: javascript python ajax django


    【解决方案1】:

    这是你应该做的:

    view_story.html:

    bla bla bla
    
    Comments:
    <ul id="comments">
    {% for comment in comments %}
       <li>{% include "comment_item.html" %}</li>
    {% endfor %}
    </ul>
    <from>Ajax form here</form>
    

    比你需要创建添加 cmets(ajax) 的视图:

    def add_comment(request):
        comment = Comment(...)
        return render_to_response('comment_item.html', {'comment': comment})
    

    因此,在您将 ajax 查询提交到 add_comment 视图后,您将获得评论的内容(一条评论).. 之后只需将其推送到列表中.. f.e.像这样使用 jQuery:

    $('ul#comments').append('<li>'+comment_content+'</li>')
    

    【讨论】:

    • 所以选项 2。这似乎是共识(如果 3 是共识)。谢谢!
    • 这也是我所做的。似乎最干燥。
    • 但这不是 DRY!您正在重复您的“模板”代码,这在此示例中非常简单。在此之后,我敢打赌你有一天会说“我刚刚更新了我的视图,触摸了 view_story.html....哦等等!”
    • @Mauricio 非常干燥 - 请注意 comment_item.html - 包含在内且从不重复(并在列表 cmets 模板和 ajax 响应中使用)
    【解决方案2】:

    我认为选项 2 是最好的。它是增量的(仅在添加评论时再渲染一条评论),并重新使用渲染。如果您不喜欢从 Ajax 请求中仅返回 HTML,则将响应设为 JSON 结构,其中仅包含 HTML 作为一个组件。然后你也可以携带状态(或其他)而不需要额外的请求来获取 HTML。

    选项 1 很浪费:服务器应该按照页面首次出现的方式呈现页面。

    选项3也很浪费:为什么要两次请求添加一条评论?

    【讨论】:

    • 是的,我同意。为了完整起见,我只是想涵盖各种可能性。
    【解决方案3】:

    还有选项4:

    复制列表中的现有元素并更改其值。这当然不如模板灵活。您可以复制隐藏元素来处理列表为空的情况。

    您也可以尝试选项 2b:

    像选项 2 一样在服务器上生成 HTML,但不是直接访问数据库,而是将生成例程传递给 JSON(或可以轻松转换为 JSON 的对象)。这涉及到更多的工作,但这意味着您在编写自己的网站的同时也在有效地编写 API。

    选项 1 是任何非 Web 应用程序都会使用的。尽管搜索引擎处理 AJAX 的能力有所提高,但仍强烈建议以 HTML 格式返回所有内容。我认为 Javascript 在所有现代浏览器中都足够快,除了大页面 1 之外,除了 SEO 问题之外,这将是相当合理的。

    还有选项 5 - 在服务器上使用 Javascript 来生成页面并在客户端上使用相同的代码。这可能是最复杂的方法,除非你真的有充分的理由,否则我不会推荐它。

    【讨论】:

      猜你喜欢
      • 2020-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-11
      • 2012-01-11
      • 1970-01-01
      相关资源
      最近更新 更多