0

我有一个可以在浏览器中完美运行的网络应用程序——无论是在桌面还是移动设备上。当我尝试通过添加来美化它时,问题就来了:

<meta name="apple-mobile-web-app-capable" content="yes" />

这也很好用——直到我需要删除应用程序中的记录为止。

我也在使用我发现的这个伟大的要点 - https://gist.github.com/1042167来阻止应用程序切换到移动 safari:

<script type="text/javascript">
    (function(document,navigator,standalone) {
        // prevents links from apps from oppening in mobile safari
        // this javascript must be the first script in your <head>
        if ((standalone in navigator) && navigator[standalone]) {
            var curnode, location=document.location, stop=/^(a|html)$/i;
            document.addEventListener('click', function(e) {
                curnode=e.target;
                while (!(stop).test(curnode.nodeName)) {
                    curnode=curnode.parentNode;
                }
                // Conditions to do this only on links to your own app
                // if you want all links, use if('href' in curnode) instead.
                if(
                    'href' in curnode && // is a link
                    (chref=curnode.href).replace(location.href,'').indexOf('#') && // is not an anchor
                    (   !(/^[a-z\+\.\-]+:/i).test(chref) ||                       // either does not have a proper scheme (relative links)
                        chref.indexOf(location.protocol+'//'+location.host)===0 ) // or is in the same protocol and domain
                ) {
                    e.preventDefault();
                    location.href = curnode.href;
                }
            },false);
        }
    })(document,window.navigator,'standalone');
</script>

我想知道这是否可以改变,所以 data-method="delete" 会很好玩吗?在那一刻——当我点击“删除”时——“你确定吗?” 确认框挂起一两秒钟,然后将我转回同一显示页面,没有发生删除...

4

2 回答 2

0

问题是location.href = curnode.href;将请求更改为GET请求,尽管我对POSTPUT请求的行为不一致。因此,当您有一些路线时,例如:

GET     /photos             index
POST    /photos             create
GET     /photos/new         new
GET     /photos/:id/edit    edit
GET     /photos/:id         show
PUT     /photos/:id         update
DELETE  /photos/:id         destroy

和路线最终重新路由update到。我的 hacky(希望是临时的)解决方案是为那些被重新路由的请求创建自定义路由。所以你会添加:destroyshow

match "update" => "Photos#update", :as => :update_photo
match "destroy" => "Photos#destroy", :as => :destroy_photo

我知道,我知道,这不是 Rails 约定,但它应该可以工作。

于 2013-02-08T23:19:47.890 回答
0

因此,我将根据您所写的内容假设您正在使用(捆绑)jquery-ujs为您处理删除链接,因为这听起来就像您提到的那样data-method

处理程序删除链接的工作方式与ujs您可能期望的不同。这是jquery-ujs来源的相关位:

// Handles  "data-method" on links such as:
// <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
    handleMethod: function(link) {
      var href = rails.href(link),
        method = link.data('method'),
        target = link.attr('target'),
        csrf_token = $('meta[name=csrf-token]').attr('content'),
        csrf_param = $('meta[name=csrf-param]').attr('content'),
        form = $('<form method="post" action="' + href + '"></form>'),
        metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';

      if (csrf_param !== undefined && csrf_token !== undefined) {
        metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
      }

      if (target) { form.attr('target', target); }

      form.hide().append(metadata_input).appendTo('body');
      form.submit();
    },

因此,您可以看到实际发生的情况是动态创建表单(使用所需csrf数据)然后提交。

在这种情况下,您链接到的 gist 中的委托click处理程序方法将不起作用,因为 rails js 会return: false单击链接,该链接具有data-method阻止您的处理程序触发的属性。

最简单的做法可能是根据代码滚动您自己的(基于 ajax 的)删除处理程序ujs。为简洁起见,我使用出色的jQuery 表单插件来处理实际提交:

function handleDeleteLink(endpoint){
  var confirmed = confirm("Are you sure you want to delete this record?"),
    csrf_token = $('meta[name=csrf-token]').attr('content'),
    csrf_param = $('meta[name=csrf-param]').attr('content'),
    form = $('<form method="post" action="' + endpoint + '"></form>'),
    metadata_input = '<input name="_method" value="delete" type="hidden" />',
    deleteOptions = {
      beforeSubmit: function(){
        //handle ajax start
      },
      success: function(el){
        //hand success
      },
      error: function(){

      }
    };
    if (csrf_param !== undefined && csrf_token !== undefined) {
      metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
    }
    if (confirmed){
      form.hide()
          .append(metadata_input)
          .appendTo('body')
          .submit(function(e){
            e.preventDefault();
            $(this).ajaxSubmit(options);
          })
          .submit();
    }
}

在您看来,只需将您的替换data-method为 say 类delete-link并通过事件委托进行绑定(或者如果您愿意,也可以使用不同的数据属性):

$('body').on('click', '.delete-link', function(e){ e.preventDefault(); handleDeleteLink(e.target.href); }

于 2012-11-01T15:22:57.510 回答