【问题标题】:Sinatra: Routes that do not routeSinatra:不路由的路由
【发布时间】:2014-01-13 16:45:24
【问题描述】:

我的 Sinatra webapp 有一个用户可以删除的文章列表。我添加了一个 jQuery 动画,以使已删除的文章在 Sinatra 路由执行实际(DB)删除之前消失。代码很简单:

# 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"));
});

在我的原始代码中改变了三件事:

  1. 在脚本中添加preventDefault,防止链接被跟踪;
  2. 链接请求现在由 jQuery 完成,使用 get;
  3. 修改了 Sinatra 路由,使其不再重定向到“/”。

代码如下:

# app.rb
get '/delete/articles/:id' do
    Articles.get(params[:id]).destroy
end

作为对初学者(就像我自己)的说明,这条get 路线与最佳实践不一致。它应该是delete 路由。我最终会解决这个问题。

感谢@exobrain 和@Amadan 的回答。


附注:

修复了get 路由。所需要的只是改变

$.get($(this).children("a").attr("href"));

$.ajax({ url: $(this).children("a").attr("href"), type: "delete"});

然后在实际的 Sinatra 应用程序上将 get '/delete/articles/:id' do 转换为 delete '/delete/articles/:id' do

【问题讨论】:

    标签: jquery routes sinatra


    【解决方案1】:

    如果您通过 AJAX 提交到/delete/articles/...,实际页面将保持未刷新状态。 (您没有显示提交代码。)您可以简单地从控制器返回"",而不是重定向空白正文。

    如果你不使用 AJAX,那么淡出是多余的;您将需要该重定向。

    【解决方案2】:

    使用get 请求删除资源有点奇怪,但无论如何,您可以使用ajax 来做到这一点。我假设.link-delete 是一个a 标签,并且有一个指向Sinatra 端点的href 属性。以下代码将阻止浏览器 (preventDefault) 跟踪链接,然后对链接指向的 url 执行 AJAX get 请求。当请求完成并返回时,在回调中进行淡出。

    $(".lnk-delete").click(function(e) {
      e.preventDefault();
      $.get(this.href, function() {
        var id = $(this).closest("article").attr("id");
        $("#"+id).fadeToggle(1000);
      }
    });
    

    【讨论】:

    【解决方案3】:

    不要使用重定向,而是在带有correct status code 的路由末尾使用halt。您还应该按照建议删除该 GET。

    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 有动词是有原因的。不要使用$.get,使用$.ajax 并传递正确的动词,即DELETE。请参阅链接中的类型

    请注意,动词也不再需要出现在 URL 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多