简体   繁体   English

最初渲染页面并使用相同的模板HTML通过AJAX更新

[英]Render page initially and update via AJAX using the same template HTML

Let's say you have a view called "View Story" which is just a web page rendered on the backend via Python/Django. 假设您有一个名为“View Story”的视图,它只是通过Python / Django在后端呈现的网页。 On that page there's a list of comments at the bottom rendered as part of the "View Story" template using Django's templating system (in a loop). 在该页面上,使用Django的模板系统(在循环中)作为“View Story”模板的一部分呈现在底部的注释列表。 This page also allows you to add a comment to the list. 此页面还允许您向列表添加注释。 This is done through AJAX and the page is updated with the new comment (without sending a new full page request). 这是通过AJAX完成的,页面使用新评论进行更新(不发送新的整页请求)。

Now, when adding the new comment to the end of the list I want the HTML that's generated for this new comment (something inside an <li> ) to use the exact same code that was used to generate the original comments sent to the client via the original request. 现在,当将新注释添加到列表末尾时,我希望为此新注释生成的HTML( <li> )使用与生成通过客户端发送到客户端的原始注释完全相同的代码原始请求。

There's multiple ways to do this: 有多种方法可以做到这一点:

  1. Have the initial rendering throw the comment data into a javascript variable and once the page is rendered add the content via javascript. 让初始渲染将注释数据抛出到javascript变量中,一旦页面呈现,就通过javascript添加内容。 Then when new comments are added that same javascript can be used to render the new one. 然后,当添加新注释时,可以使用相同的javascript来呈现新的注释。 The problem: from a search engine perspective I'm not sure google would be able to index the comments if they're generated after the page has been rendered - I'm guessing not 问题:从搜索引擎的角度来看,我不确定google是否能够在页面呈现之后生成它们的索引 - 我猜不是

  2. Each time a new comment is added via AJAX, have the ajax request return the actual HTML to put on the page rather than just the JSON data of the new comment. 每次通过AJAX添加新注释时,请让ajax请求返回放在页面上的实际HTML,而不仅仅是新注释的JSON数据。 The HTML can be generated using the same template snippet that was used to render the original page. 可以使用用于呈现原始页面的相同模板片段生成HTML。 The problem with this is that it ties that AJAX request to a particular view or a way of rendering it which I don't like. 这个问题是它将AJAX请求与特定视图或我不喜欢的渲染方式联系起来。

  3. Similar to #2 except that a separate request is made to retrieve the HTML for the new comment or maybe all the comments and the list is just wiped and re-rendered. 与#2类似,不同之处在于单独请求检索新注释的HTML或者可能是所有注释,并且只是擦除并重新呈现列表。 Don't like that cause it's deeply inefficient and unnecessarily time-consuming. 不喜欢它,因为它效率极低且不必要地耗费时间。

So, to summarize, I want a way to avoid duplicating Template/HTML code for a single view. 因此,总而言之,我想要一种方法来避免为单个视图复制模板/ HTML代码。 And I would like some advice on what has worked for others because I'm pretty sure this is a common case irregardless of the technology on the back-end. 我想对其他人有用的建议,因为我很确定这是一个常见的情况,无论后端的技术如何。

Thanks! 谢谢!

Here is what you should do: 这是你应该做的:

view_story.html: 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>

than you need to create view for adding comments(ajax): 比你需要创建视图添加注释(ajax):

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

So after you submit your ajax query to add_comment view you will get the content of the comment(one comment).. after that just push it to list.. fe using jQuery like this: 因此,在向ad_comment视图提交ajax查询后,您将获得评论的内容(一条评论)..之后只需将其推送到列表.. fe使用jQuery,如下所示:

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

I think option 2 is best. 我认为选项2是最好的。 It's incremental (only renders one more comment when a comment is added), and re-uses the rendering. 它是增量的(仅在添加注释时再渲染一条注释),并重新使用渲染。 If you don't like returning just HTML from an Ajax request, then have the response be a JSON structure which includes the HTML as just one component. 如果您不喜欢仅从Ajax请求返回HTML,那么将响应设置为JSON结构,其中HTML仅包含一个组件。 Then you can also carry status (or whatever) without an extra request to get the HTML. 然后你也可以携带状态(或其他),而无需额外的请求来获取HTML。

Option 1 is wasteful: the server should render the page as it should first appear. 选项1是浪费的:服务器应该首先显示页面。

Option 3 is also wasteful: why make two requests to add a single comment? 选项3也是浪费:为什么要两个请求添加一个注释?

There is also option 4: 还有选项4:

Copy an existing element in the list and change its values. 复制列表中的现有元素并更改其值。 This is of course less flexible than templates. 这当然不如模板灵活。 You can copy a hidden element instead to handle the case where the list is empty. 您可以复制隐藏元素,以处理列表为空的情况。

You could also try option 2b: 您也可以尝试选项2b:

Generate the HTML on the server like option 2, but instead of directly accessing the database, pass the generation routine the JSON (or an object that can easily be converted to JSON). 像服务器2一样在服务器上生成HTML,但不是直接访问数据库,而是将生成例程传递给JSON(或者可以轻松转换为JSON的对象)。 This involves more work, but means that you are effectively writing an API at the same time you are writing your own website. 这涉及更多工作,但意味着您在编写自己的网站的同时有效地编写API。

Option 1 is what any non-web application would use. 选项1是任何非Web应用程序将使用的。 Even though search engines are improving in their ability to handle AJAX, it is still strongly recommended to return all the content in HTML. 尽管搜索引擎在处理AJAX方面的能力正在提高,但仍然强烈建议以HTML格式返回所有内容。 I think Javascript is fast enough in all modern browsers that except for huge pages 1 would be quite reasonable except for the SEO issue. 我认为Javascript在所有现代浏览器中都足够快,除了大页面1之外,除了搜索引擎优化问题之外,它是非常合理的。

There is also option 5 - use Javascript on the server to generate the page and use the same code on the client. 还有选项5 - 在服务器上使用Javascript生成页面并在客户端上使用相同的代码。 This is probably the most complicated approach and I wouldn't recommend it unless you really have a good reason. 这可能是最复杂的方法,除非你有充分的理由,否则我不推荐它。

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

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