Jquery 西纳特拉:不选择路线的路线
My Sinatra webapp有一个用户可以删除的文章列表。我添加了一个jQuery动画,使被删除的文章在Sinatra路由执行实际(DB)删除之前逐渐消失。代码是基本的:Jquery 西纳特拉:不选择路线的路线,jquery,routes,sinatra,Jquery,Routes,Sinatra,My Sinatra webapp有一个用户可以删除的文章列表。我添加了一个jQuery动画,使被删除的文章在Sinatra路由执行实际(DB)删除之前逐渐消失。代码是基本的: # script.js $(".lnk-delete").click(function() { var id = $(this).closest("article").attr("id"); $("#"+id).fadeToggle(1000); }); # app.rb get '/delet
# script.js
$(".lnk-delete").click(function()
{
var id = $(this).closest("article").attr("id");
$("#"+id).fadeToggle(1000);
});
# app.rb
get '/delete/articles/:id' do
Articles.get(params[:id]).destroy
redirect to('/')
end
问题是,代码会重新路由到同一个页面,这是不必要的,因为已删除的文章不再显示。重新路由不仅会产生不必要的负载,还会将用户带回到页面顶部(使体验变得混乱和烦人)
我环顾四周,尝试返回HTTP代码,尝试停止(ing),尝试request.xhr函数和任何我可以在网上找到的东西,都没有用
是否有办法使路由“非路由”,即执行db.destroy并使实际页面“未刷新”
更新
下面的代码是@exobrain答案的一个稍加修改的版本,解决了我的问题
# script.js
$(".lnk-delete").click(function(clicked) {
clicked.preventDefault();
var id = $(this).closest("article").attr("id"); $("#"+id).fadeToggle(1000);
$.get($(this).children("a").attr("href"));
});
在我的原始代码中有三件事发生了变化:
preventDefault
,以防止链接被跟踪李>
get
李>
# app.rb
get '/delete/articles/:id' do
Articles.get(params[:id]).destroy
end
作为初学者(和我自己)的注意事项,此get
路线与最佳实践不一致。它应该是一条delete
路线。我最终会解决的
谢谢,@exobrain&@Amadan,谢谢你的回答
附言: 修复了
get
路径。一切都在改变
$.get($(this).children("a").attr("href"));
到
然后在实际的Sinatra应用程序上
get'/delete/articles/:id'do
到delete'/delete/articles/:id'do
。如果您通过AJAX提交到/delete/articles/..
,实际页面将保持不变。(您没有显示提交代码。)您只需从控制器返回“
”,而无需重定向空白正文
如果您没有使用AJAX,那么淡出是多余的;您将需要这种重定向。使用
get
请求来删除资源有点奇怪,但尽管如此,您可以使用ajax来完成这一点。我假设.link delete
是一个a
标记,并且有一个href
属性指向Sinatra端点。以下代码将阻止浏览器跟随链接(preventDefault
),然后对链接指向的url执行AJAXget
请求。当请求完成并返回时,在回调中执行淡出
$(".lnk-delete").click(function(e) {
e.preventDefault();
$.get(this.href, function() {
var id = $(this).closest("article").attr("id");
$("#"+id).fadeToggle(1000);
}
});
在路由的末尾使用,而不是重定向。你也应该像别人建议的那样摆脱这种习惯
get '/delete/articles/:id' do
Articles.get(params[:id]).destroy
redirect to('/')
end
变成
get '/articles/:id' do
# get the article here
end
delete '/articles/:id' do
Articles.get(params[:id]).destroy
halt 200
# I'd also return a representation of the deleted article
# or perhaps it's ID
# but maybe that's just me
end
HTTP有动词是有原因的。不要使用$。获取,使用并传递正确的动词,即DELETE。请参见链接中的键入
请注意,动词也不再需要出现在URL中。提交代码只是一个html标记,URL指向/delete/articles/:id(其中:id已被文章的id替换)。淡出的效果和我预期的一样,所以它并不完全是多余的。我只是不想重新加载页面。但是,如果我正确理解了您的答案,如果我希望它能够工作,我需要通过AJAX提交来编写代码。谢谢你的建议,阿玛丹。呃。。。是 啊这是另一个需要解决的问题。我尝试使用标记的data方法,但请求仍然作为get请求传递。我读了一些关于Sinatra的:方法\u override config的文章,我可能稍后会尝试用它来解决这个问题。关于手头的问题,感谢您提供代码片段。它没有完全起作用-显然preventDefault()没有被触发,我在完成时得到了一个空白页-但这没关系。有了你的回答和@Amadan's,我可以进步一点。我将研究AJAX请求并重写代码。谢谢你!这并不奇怪,它是危险的。它可以被谷歌机器人收集,这意味着若它可以访问带有删除链接的页面,它可以擦除你们的整个数据库。GET请求应该不能在服务器上更改任何内容,除了日志记录之类的附带内容。对于任何更改,您都应该执行POST、PUT或DELETE(您都不能从普通的
:POST可以通过表单完成,而这三项都可以通过JavaScript完成)。
get '/articles/:id' do
# get the article here
end
delete '/articles/:id' do
Articles.get(params[:id]).destroy
halt 200
# I'd also return a representation of the deleted article
# or perhaps it's ID
# but maybe that's just me
end