Gur*_*ngh 3 ruby ruby-on-rails ruby-on-rails-4
所以我有这样的布局:
家用/ index.html.erb:
<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-book optionseach" aria-hidden="true"></i>All stories
<% end %>
</div>
<div id="content" class="">
</div>
Run Code Online (Sandbox Code Playgroud)
在posts_controller.rb中
我有:
def index
@posts = Post.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
Run Code Online (Sandbox Code Playgroud)
在stories_controller.rb中
我有:
def index
@stories = Story.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
Run Code Online (Sandbox Code Playgroud)
在我的views/posts/index.js.erb中
$("#content").html("<%= j (render 'posts') %>");
Run Code Online (Sandbox Code Playgroud)
在我的views/stories/index.js.erb中
$("#content").html("<%= j (render 'stories') %>");
Run Code Online (Sandbox Code Playgroud)
我也有_posts.html.erb在views/posts和_stories_html.erb中views/stories
发生的事情是,当我点击帖子按钮时,我呈现视图,但是当我点击故事按钮时,没有任何渲染?
Aru*_*han 18
好的,在进入解决方案之前,让我们了解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(异步Javascript XML)的内容更新页面的某些部分.
典型的AJAX请求是这样的.你让一个请求到服务器,但这次异步和服务器响应XML,而不是HTML和Javascript解析XML文档更新页面的一部分.尽管它现在被称为AJAX,但是现在,JSON用于跨服务交换信息.
所以,做一个AJAX请求,我们需要点击它时,发送一个链接XMLHttpRequest(异步请求)和服务器端应回应JSON或XML或然后脚本应该解析响应并更新DOM(文档对象模型).使得在AJAX请求Vanilla JS(普通的JavaScript)是复杂的,人们通常使用Jquery的ajax方法来发出一个AJAX请求(较少的代码行).有关更多信息,请参见http://api.jquery.com/jquery.ajax/.
但是rails,它更容易.我们可以使用UJS(Unobtrusive Javascript)发出AJAX请求.让我们看看它在行动.
要使链接发送AJAX请求,您需要remote: true在link_to帮助程序中进行设置.这会data-remote=true在生成的HTML中添加一个.
例如以下的erb
<%= link_to "All books", books_path, remote: true %>
Run Code Online (Sandbox Code Playgroud)
生成html
<a data-remote="true" href="/books">All books</a>
Run Code Online (Sandbox Code Playgroud)
好.现在我们都准备提出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>
Run Code Online (Sandbox Code Playgroud)
我假设你有控制器,模型和视图设置.同时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
Run Code Online (Sandbox Code Playgroud)
注意:format这里对应于可返回的格式html,js,xml或json.
posts_path其中一个url_helper指向posts#index,意味着每当向rails应用程序中的服务器发出请求时,它首先到达路由器并被分派到controller指定的相应操作中.routes.rb
在这种情况下,如果我们发出请求http://localhost:3000/books,则将请求发送到books#index action.在操作中,您可以从中获取数据database并将响应发送到客户端.
由于我们对AJAX感兴趣并且我们已经指定remote:true,因此rails会期望将JS响应返回给客户端(即script,负责动态呈现内容的a).
我将解释如何处理AJAX请求BooksController,您可以将相同的想法应用于其他控制器.(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
Run Code Online (Sandbox Code Playgroud)
我们在这里所做的就是告诉控制器index.js.erb如果客户端请求JS响应或index.html.erb在HTML响应的情况下呈现则呈现.rails如何知道渲染index.html.erb或者index.js.erb我们没有指定要渲染的文件?这是什么铁路受欢迎.Rails遵循Convention Over Configuration.
实际上,controller从action名称推断出要呈现的模板.
下一步是利用@books更新#contentdiv.在添加代码以呈现所有书籍之前,我们需要一个模板来渲染吗?这是部分进入的地方.部分是可重复使用的view' and a partial in rails is prefixed with '_'. For example:_books.html.erb is a partial for书籍.
创建一个部分 app/views/books/_books.html.erb
<% @books.each do |book| %>
<div class="book">
#Display the fields
</div>
<% end %>
Run Code Online (Sandbox Code Playgroud)
现在创建app/views/books/index.js.erb并添加以下内容:
$("#content").html("<%= j (render 'books') %>");
Run Code Online (Sandbox Code Playgroud)
这个单行将使部分_books.html.erb成为#contentdiv.等待.它是如何工作的?让我们分成几块.
里面的任何东西<%= %>都是ruby代码.它的执行和替换值代替<%= %>.该erb模板engline允许你写ruby里面的代码javascript.那么,这有什么用呢?
<%= j (render 'books') %>
Run Code Online (Sandbox Code Playgroud)
它将books/_books.html.erb从参数中推断出render.它返回由生成的html _books.html.erb.
怎么j办?它实际上是escape_javascript方法的别名.它用于转义从partial返回的内容_books.html.erb.
解释escapinghtml 的原因会使这个答案更长.我强烈建议你在这个 SO线程中阅读kikito的答案(第3个).
所以,我们将html从partial传递为字符串(注意引号<%= %>)到div中html添加的方法#content.而已!
我建议您检查服务器日志并浏览NetworkDeveloper工具中的选项卡,以深入了解AJAX的工作原理.
对其他控制器(PostsController和StoriesController)执行相同操作.
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
2703 次 |
| 最近记录: |