好了,进入了解决方案之前,让了解request-response
周期。
当您搜索http://stackoverflow.com时,发生了什么是您从client
(您的浏览器)发送到StackOverflow(SO)server
的请求。客户端和服务器通过HTTP
协议进行通信,并且如果用户请求服务器知道的某些内容,则服务(发送)响应(html,css,js文件)。浏览器知道如何显示从服务器接收到的html内容。每个浏览器都有自己的样式表(user-agent-stylesheet
),它也适用于从服务器发回的HTML页面中链接的CSS文件中的样式。请注意,这一切都发生在同步和虽然server
正在处理客户端的请求,浏览器选项卡inactive
作为其等待服务器的响应。点击链接时会发生同样的过程。它向服务器创建一个新的请求。
服务器的响应可能是HTML
,JSON
,XML
等等。您可能已经注意到,synchronous
通信不是我们总想要的。
如果我们做一个新的synchronous
请求时,浏览器获取HTML
,CSS
和JS
和image
文件一遍(让我们不要进入高速缓存)。我们不想为每个请求更新整个页面。
通常,只有部分页面在请求后被更新,并提供良好的用户体验。
这是Javascript擅长的地方。它有权异步向服务器发出请求(网页不重新加载),并使用名为AJAX
(Asynchronous Javascript XML)的东西更新页面的某些部分。
一个典型的AJAX请求是这样的。您向服务器发出请求,但是这次是异步的,服务器以XML
而不是HTML
和Javascript
解析XML
文档更新页面部分。虽然现在有一天,JSON被称为AJAX,用于跨服务交换信息。
所以,做一个AJAX请求,我们需要点击它时,发送XMLHttpRequest
(异步请求)和服务器端应JSON
或XML
或响应,然后脚本应该解析响应和更新的链接DOM
(Document Object Model )。在Vanilla JS
(普通javascript)中发出AJAX请求很复杂,人们通常使用Jquery
的ajax
方法来发出AJAX请求(少量代码行)。有关更多信息,请参阅http://api.jquery.com/jquery.ajax/。
但在rails
,它更容易。我们可以使用UJS
(Unobtrusive Javascript)发出AJAX请求。让我们看看它的行动。
要使链接发送AJAX请求,您需要在link_to
帮助程序中设置remote: true
。这会在生成的HTML中添加一个data-remote=true
。
例如下面的erb
<%= link_to "All books", books_path, remote: true %>
生成HTML
<a data-remote="true" href="/books">All books</a>
确定。现在我们都准备提出AJAX
请求。修改你的代码为
<div style="margin-top:50px;" class="wrapper">
<div class="optionscontainer btn-group btn-group-justified">
<%= link_to posts_path, class:"options btn btn-primary", remote: true do %>
<i class="fa fa-book optionseach" aria-hidden="true"></i>All posts
<% end %>
<%= link_to stories_path, class:"options btn btn-primary", remote: true do %>
<i class="fa fa-rss optionseach" aria-hidden="true"></i>All stories
<% end %>
<%= link_to books_path, class:"options btn btn-primary", remote: true do %>
<i class="fa fa-users optionseach" aria-hidden="true"></i>All books
<% end %>
</div>
<div id="content">
<!-- The content goes here -->
</div>
我假设你有控制器,模型和视图设置。还可以在终端中执行rake routes
以查看您的应用程序的现有路线。您应该看到以下内容(顺序并不重要)
Prefix Verb URI Pattern Controller#Action
posts GET /posts(.:format) posts#index
stories GET /stories(.:format) stories#index
books GET /books(.:format) books#index
注:format
这里对应于可html
,js
,xml
或json
返回的格式。
posts_path
在指向posts#index
,每当请求以rails
应用向服务器发出意味着url_helper
之一,它首先到达路由器和被分派到在routes.rb
指定在对应controller
动作在这种情况下,如果我们向http://localhost:3000/books
发出请求,则将请求发送到books#index操作。在操作中,您可以从database
中获取数据并将响应发送给客户端。
由于我们对AJAX感兴趣,并且我们指定了remote:true
,因此rails会期望将一个JS
响应返回给客户端(即负责动态呈现内容的script
)。
我将解释如何处理BooksController
的AJAX请求,并且您可以对其他控制器应用相同的想法(posts
和stories
)。
class BooksController < ApplicationController
def index
@books = Book.all
respond_to do |format|
format.html #looks for views/books/index.html.erb
format.js #looks for views/books/index.js.erb
end
end
#other actions
end
所有我们在这里所做的是告诉控制器来呈现index.js.erb
如果一个JS响应客户端的请求或HTML响应的情况下渲染index.html.erb
。当我们没有指定要呈现的文件时,rails如何知道如何渲染index.html.erb
或index.js.erb
?多数民众赞成什么铁轨流行for.Rails如下Convention Over Configuration。
实际上,controller
推断模板从action
名称渲染。
下一步是利用@books
来更新#content
div。在添加代码来呈现所有图书之前,我们需要一个模板来呈现对吗?这就是部分进来。部分是可重复使用的书籍。
创建一个局部app/views/books/_books.html.erb
<% @books.each do |book| %>
<div class="book">
#Display the fields
</div>
<% end %>
现在创建app/views/books/index.js.erb
,并添加以下内容:
$("#content").html("<%= j (render 'books') %>");
这一个班轮将呈现局部_books.html.erb
到#content
格。等待。它是如何工作的?让它分解成碎片。
<%= %>
里面的东西都是红宝石代码。它的执行和值取代<%= %>
。 erb
模板engline允许您在javascript
中编写ruby
代码。那么,这是做什么的?
<%= j (render 'books') %>
这将使books/_books.html.erb
,从参数推断render
。它返回由_books.html.erb
生成的html。
j
是做什么用的?它实际上是escape_javascript
方法的别名。它用于转义从部分_books.html.erb
返回的内容。
解释escaping
html的原因将使这个答案更长。我强烈建议您在this SO线索中阅读kikito的回答(第3个)。
所以,我们从部分经过HTML作为字符串(注意周围<%= %>
引号),这是该#content
DIV中添加html
方法。而已!
我建议您检查服务器日志并浏览开发人员工具中的Network
选项卡,以深入了解AJAX的工作原理。
对其他控制器(PostsController
和StoriesController
)做相同的操作。
希望这会有所帮助。
你怎么想使它们?作为一个AJAX请求?你知道如何在控制器上创建一个动作吗? – yogodoshi
我是新来的rails和web开发,如果AJAX是最好的方式,请做一个例子 –