Sinatra 视图在一些删除请求后不刷新
Sinatra view doesn't refresh after some delete requests
在我的 Sinatra 视图中,我有一个 table,它将显示我数据库中的所有记录。当我点击删除一条记录时,我会调用jqueryajax发送删除请求。然后我的路线将处理请求,删除数据库中的记录并将应用程序重定向到其主页。
问题是删除后视图没有刷新,仍然显示一些旧数据。当我关闭浏览器并再次打开它时,即使删除请求已返回 200 代码状态,数据仍然存在于视图中。
# application_controller.rb
require 'sinatra'
require 'sinatra/reloader'
require './application_helper' if development?
enable :logging
helpers ApplicationHelper
...
delete '/delete/:record_id' do
id = get_record_id
delete_record id
redirect '/'
end
get '/' do
@links = get_all @user_ip
erb :index, { :layout => :layout }
end
下面是视图的简化代码:
# index.erb
<% if !@links.empty? %>
<div class="table-responsive" style="margin-top: 30px">
<table class="table table-striped table-hover" style="width: 600px">
<thead>
<tr>
<th>Original URL</th>
<th>Short URL</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<% @links.each do |record| %>
<tr>
<td><a href=<%= record.long_url %>><%= record.long_url %></td>
<td><a href=<%= record.id %>><%= record.short_url %></td>
<td>
<button class="btn btn-default" onClick="deleteRecord(<%= record.id %>)">
<span class="glyphicon glyphicon-trash" style="color: red"></span>
</button>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<% end %>
这是 GitHub 上的完整源代码:https://github.com/huyvohcmc/bitly
好吧,经过几个小时的谷歌搜索,我终于可以通过稍微更改控制器和视图来使其工作:
# application_controller.rb
delete '/delete/:record_id' do
id = get_record_id
delete_record id
redirect '/'
end
# index.erb
var deleteRecord = function (id) {
$.ajax({
url: '/delete/' + id,
type: 'DELETE',
success: function(data) {
location.reload();
}
})
}
基本上,删除记录后我必须手动重新加载页面。我还不知道 Sinatra 是否支持这个功能,但现在这个方法很有用:)
正在重新加载一个页面并且正在重定向到一个页面。
当您使用 Sinatra 的 redirect
方法时,它会响应 302 or 303 status code。
# @see https://github.com/sinatra/sinatra/blob/v2.0.0/lib/sinatra/base.rb#L271
# Halt processing and redirect to the URI provided.
def redirect(uri, *args)
if env['HTTP_VERSION'] == 'HTTP/1.1' and env["REQUEST_METHOD"] != 'GET'
status 303
else
status 302
end
# According to RFC 2616 section 14.30, "the field value consists of a
# single absolute URI"
response['Location'] = uri(uri.to_s, settings.absolute_redirects?, settings.prefixed_redirects?)
halt(*args)
end
通过调用 redirect "/"
,您要求浏览器重定向到“/”,这通常会触发一个新页面。但是,您已经在该页面上,因此 jQuery 代码正在接收重定向 并且 您要求在成功时通过 location.reload()
重新加载。成功通常通过使用 2xx 代码进行响应来表示,因此我认为重定向意味着成功处理程序未触发,并且因为浏览器意识到您已经在页面上,重定向要求它不会尝试一个重定向,你最终没有新数据。
路线可能看起来更像这样:
delete '/delete/:record_id' do
id = get_record_id
delete_record id
halt 200 # think about handling errors too
end
成功处理程序现在应该触发。这个故事的寓意,明确你想做什么,不要依赖副作用(比如重定向共享重新加载的一些属性)来做你想做的事。
在我的 Sinatra 视图中,我有一个 table,它将显示我数据库中的所有记录。当我点击删除一条记录时,我会调用jqueryajax发送删除请求。然后我的路线将处理请求,删除数据库中的记录并将应用程序重定向到其主页。
问题是删除后视图没有刷新,仍然显示一些旧数据。当我关闭浏览器并再次打开它时,即使删除请求已返回 200 代码状态,数据仍然存在于视图中。
# application_controller.rb
require 'sinatra'
require 'sinatra/reloader'
require './application_helper' if development?
enable :logging
helpers ApplicationHelper
...
delete '/delete/:record_id' do
id = get_record_id
delete_record id
redirect '/'
end
get '/' do
@links = get_all @user_ip
erb :index, { :layout => :layout }
end
下面是视图的简化代码:
# index.erb
<% if !@links.empty? %>
<div class="table-responsive" style="margin-top: 30px">
<table class="table table-striped table-hover" style="width: 600px">
<thead>
<tr>
<th>Original URL</th>
<th>Short URL</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<% @links.each do |record| %>
<tr>
<td><a href=<%= record.long_url %>><%= record.long_url %></td>
<td><a href=<%= record.id %>><%= record.short_url %></td>
<td>
<button class="btn btn-default" onClick="deleteRecord(<%= record.id %>)">
<span class="glyphicon glyphicon-trash" style="color: red"></span>
</button>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<% end %>
这是 GitHub 上的完整源代码:https://github.com/huyvohcmc/bitly
好吧,经过几个小时的谷歌搜索,我终于可以通过稍微更改控制器和视图来使其工作:
# application_controller.rb
delete '/delete/:record_id' do
id = get_record_id
delete_record id
redirect '/'
end
# index.erb
var deleteRecord = function (id) {
$.ajax({
url: '/delete/' + id,
type: 'DELETE',
success: function(data) {
location.reload();
}
})
}
基本上,删除记录后我必须手动重新加载页面。我还不知道 Sinatra 是否支持这个功能,但现在这个方法很有用:)
正在重新加载一个页面并且正在重定向到一个页面。
当您使用 Sinatra 的 redirect
方法时,它会响应 302 or 303 status code。
# @see https://github.com/sinatra/sinatra/blob/v2.0.0/lib/sinatra/base.rb#L271
# Halt processing and redirect to the URI provided.
def redirect(uri, *args)
if env['HTTP_VERSION'] == 'HTTP/1.1' and env["REQUEST_METHOD"] != 'GET'
status 303
else
status 302
end
# According to RFC 2616 section 14.30, "the field value consists of a
# single absolute URI"
response['Location'] = uri(uri.to_s, settings.absolute_redirects?, settings.prefixed_redirects?)
halt(*args)
end
通过调用 redirect "/"
,您要求浏览器重定向到“/”,这通常会触发一个新页面。但是,您已经在该页面上,因此 jQuery 代码正在接收重定向 并且 您要求在成功时通过 location.reload()
重新加载。成功通常通过使用 2xx 代码进行响应来表示,因此我认为重定向意味着成功处理程序未触发,并且因为浏览器意识到您已经在页面上,重定向要求它不会尝试一个重定向,你最终没有新数据。
路线可能看起来更像这样:
delete '/delete/:record_id' do
id = get_record_id
delete_record id
halt 200 # think about handling errors too
end
成功处理程序现在应该触发。这个故事的寓意,明确你想做什么,不要依赖副作用(比如重定向共享重新加载的一些属性)来做你想做的事。