0

我正在使用带有 bootstrap4 的标签输入。我希望用户单击删除标签(“x”按钮),然后将标签删除请求发送到服务器,该服务器检查是否允许用户这样做。服务器响应是或否(如果是,则删除数据库中的标签)。并且应该通知 tagsinput 从输入元素及其内部状态(在客户端)中删除标签。

据我了解,我将beforeItemRemove事件添加到 tagsinput-element 并使用event.cancel=true;取消标签的删除。像这样:

$(inputel).on('beforeItemRemove', function(event) {
  ajaxreq(..., onSuccess(r){}, onError(e,m){ event.cancel = true; });
});

但是正如您所猜想的那样, event.cancel 设置得太晚了,因为该事件已被长时间处理并在 ajax 请求完成之前退出!

我最终做的是:

event.cancel = true; // we cancel the deletion by default
$(inputel).on('beforeItemRemove', function(event) {
  ajaxreq(..., onSuccess(r){
   // ajax succeeded and server allowed to delete, let's also delete from inputel
   $(inputel).tagsinput('remove', event.item, {preventPost: true});
}, onError(e,m){});
});
// the event is returning much earlier than ajax completing
// but with event.cancel=true it does nothing until we call the 'remove'

这是正确的解决方案吗?

编辑:此处的相关文档:https ://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/ (例如搜索beforeItemRemove

EDIT2:我刚刚确认这适用于不允许用户删除标签并且服务器通过 ajax 拒绝删除它的情况。实际上,输入元素中没有任何内容被删除。但是,在用户可以并且确实删除标签的情况下,该事件会被重复触发(尽管preventPost: true我只是推测它会在没有触发 remove-event 的情况下删除)并轰炸数据库。

4

1 回答 1

0

bootstrap-tagsinput.jshttps://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/克隆和修补 JS 文件是我最后的手段,它确实有效。所以这根本不理想。另外,那里有很多引导程序“tagsinput”JS 文件,这使得这是一个非常糟糕的解决方案。

编辑在 3 个地方。

1)在注册函数addremove接受第三个参数时,他们的签名显示他们接受了 3 个参数(最后一个是选项作为带有诸如 preventPost 之类的键的对象),但下面的注册没有通过第三个参数!(请注意 arg1 是函数名称,如“add”或“remove”):

  /**
   * Register JQuery plugin
   */


   /* bliako modifies: add arg4 at the end, after arg3: */
  $.fn.tagsinput = function(arg1, arg2, arg3, arg4) {
    var results = [];

    this.each(function() {
...
      } else if(tagsinput[arg1] !== undefined) {
          // Invoke function on existing tags input
/* bliako modifies: */
var retVal = tagsinput[arg1](arg2, arg3, arg4);
/* bliako modifies: and comment out the following - which may introduce side-effects, the problem is that I can't see how these functions get an "options" 3rd arg without arg4 (arg1 is the function name, e.g."add") 
So this hopefully passes an options={preventPost: true} back to the add() and remove() functions.
*/
/*            if(tagsinput[arg1].length === 3 && arg3 !== undefined){
               var retVal = tagsinput[arg1](arg2, null, arg3);
            }else{
               var retVal = tagsinput[arg1](arg2);
            }
*/

2) 修改“添加”功能以在选项 arg 包含时不触发事件preventPost: true

      // if length greater than limit
      if (self.items().toString().length + item.length + 1 > self.options.maxInputLength)
        return;

      // raise beforeItemAdd arg
/* bliako modifies: don't trigger the &*Q&* event if preventPost == true */
if( (options == null) || ! options.hasOwnProperty('preventPost') || ! options.preventPost ){
      var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false, options: options});
      self.$element.trigger(beforeItemAddEvent);
      if (beforeItemAddEvent.cancel)
        return;
} else { console.log("tags/remove() : blocked beforeItemRemoveEvent"); }

3)与上述相同的修改,但对于“删除”功能:

        if (typeof item === "object")
          item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) ==  self.optio$
        else
          item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) ==  item; } );

        item = item[item.length-1];
      }

      if (item) {
/* bliako modifies: don't trigger the @*&*Q& event if preventPost == true */
if( (options==null) || ! options.hasOwnProperty('preventPost') || ! options.preventPost ){
        var beforeItemRemoveEvent = $.Event('beforeItemRemove', { item: item, cancel: false, options: options $
        self.$element.trigger(beforeItemRemoveEvent);
        if (beforeItemRemoveEvent.cancel)
          return;
} else { console.log("tags/remove() : blocked beforeItemRemoveEvent"); }

这个想法很简单,最好遵循以下想法 1) 允许addremove函数将第三个参数作为选项,以便您可以传递 add(item, dontpushval, {preventPost: true}); 2)修改所述函数以实际读取选项参数(因为它们的签名已经误导性地表明它们接受options参数)并且只要preventPost存在并且设置为true,就阻止触发beforeItemAddbeforeItemRemove

这只是表明“网络”是多么破碎,以及价值数十亿的优秀企业是如何建立在腐烂的粘土腿上的。

bw, bliako

ps 我很惊讶没有任何 SO 巨魔立即到达宣布这个问题无关紧要、离题、模糊、已经解决或他们当天的“计算机说不”的借口之一。也许他们都在忙于“社区”会议,以使 SO “更大”。

于 2020-05-30T18:13:31.230 回答