角度多重拖放(ng2-dragula)

Posted

技术标签:

【中文标题】角度多重拖放(ng2-dragula)【英文标题】:Angular Multiple Drag and Drop (ng2-dragula) 【发布时间】:2018-07-22 13:06:51 【问题描述】:

我正在寻找支持多重拖动的拖放库。但我找不到任何角度 2+。 ng2-dragula 支持我们想要的,除了多次拖放。任何人都可以建议任何库或如何覆盖 ng2 dragula 来实现相同的目标。 以下是我们正在寻找的功能:

    拖动到目标容器中的特定位置 拖动多个项目 拖动到同一个容器中 适用于任何类型的元素 支持复制和移动到目标

【问题讨论】:

您可以尝试angular-sortablejs 了解您的功能。 非常感谢。即使在可排序的 js 中也没有多次拖动的选项 多次拖动是什么意思? 您能否补充一下,以回答您如何为 multi darg drop 实现相同的操作? 一般情况下你可以使用 ng2-dragula 来做这个 - 找租:jsfiddle.net/tx7aym91/4 【参考方案1】:

基于this commentgithub bevacqua/dragula issue: Drag and drop multiple items #50。

我做了一些改进,允许通过所选项目拖放多个项目:https://jsfiddle.net/twfcd5hx/1/

在 ng2-dragula 上:https://stackblitz.com/edit/ng2-dragula-base-i41w6c?file=src/app/app.component.ts

相关代码(注意I've tried using the pure angular way 但没有按预期工作,一旦我找到纯角度代码就会更新):

this.dragulaService.cloned("dnd").subscribe(( clone, original, cloneType ) => 
      this.mirrorContainer = $('.gu-mirror').first();
      this.mirrorContainer.removeClass('ex-over');
      this.selectedItems = $('.ex-over');
      this.hasMultiple = this.selectedItems.length > 1 || (this.selectedItems.length == 1 && !$(original).hasClass('ex-over'));
      if (this.hasMultiple) 
        $('.gu-transit').addClass('ex-over');
        this.selectedItems = $('.ex-over');
        this.mirrorContainer.empty();
        var height = 0,
          width = 0;
        let temp = this.mirrorContainer;
        this.selectedItems.each(function (index) 
          var item = $(this);
          var mirror = item.clone(true);
          mirror.removeClass('ex-over gu-transit');
          temp.append(mirror);
          temp.css('background-color', 'transparent');
          item.addClass('gu-transit');
          var rect = item[0].getBoundingClientRect();
          height += rect.height;
          width = rect.width;
        );
        this.mirrorContainer = temp;
        this.mirrorContainer.css('height', height + 'px');
      
    );

您需要在.ts 文件上声明import $ from 'jquery'; 并安装@types/jqueryjquery

解释:

this.mirrorContainer = $('.gu-mirror').first();抓取镜像容器dragula默认创建

this.mirrorContainer.removeClass('ex-over');多选项目会有这个类,但我们不希望它出现在镜子里的那些上

this.selectedItems = $('.ex-over');获取多选项目

this.hasMultiple = this.selectedItems.length > 1 || (this.selectedItems.length == 1 && !$(original).hasClass('ex-over')); 检查是否选择了多个项目,并考虑它们从尚未选择的项目开始拖动的位置

if (this.hasMultiple)  // we have multiple items selected
    $('.gu-transit').addClass('ex-over'); // edge case: if they started dragging from an unselected item, adds the selected item class
    this.selectedItems = $('.ex-over'); // update list of selected items in case of edge case above
    this.mirrorContainer.empty();  // clear the mirror container, we're going to fill it with clones of our items
    var height = 0,
      width = 0; // will track final dimensions of the mirror container
    let temp = this.mirrorContainer; // used to temporary store this.mirrorContainer since otherwise would return undefined
    this.selectedItems.each(function (index)  // clone the selected items into the mirror container
      var item = $(this); // the item
      var mirror = item.clone(true); // clone the item
      mirror.removeClass('ex-over gu-transit'); // remove the state classes if necessary
      temp.append(mirror); //add the clone to mirror container
      temp.css('background-color', 'transparent');
      item.addClass('gu-transit'); //add drag state class to item
      var rect = item[0].getBoundingClientRect(); // update the dimensions for the mirror container
      height += rect.height;
      width = rect.width;
    );
    this.mirrorContainer = temp; // restore this.mirrorContainer value after updated
    this.mirrorContainer.css('height', height + 'px'); //set final height of mirror container
  

请注意,在下面的代码中,我使用el.remove() 来删除存储到目标元素的拖动元素,因为我已经创建了moveback()moveto() 函数(related explanation)。

this.dragulaService.drop("dnd")
  .subscribe(( name, el, target, source, sibling ) => 
    if (source.attributes[2].value === "data" && (target.attributes[3].value === "ct" || target.attributes[2].value === "target")) 
      if (this.target.length > 0) 
        this.placeholdertarget = false;
      
      if (this.data.length < 1) 
        this.placeholderdata = true;
      
      if (!this.hasMultiple) 
        let target = document.getElementsByClassName('target');
        for (let i = target.length - 1; i >= 0; i--) 
          if (target[i].className.includes('ex-over') && i >= 0) 
            this.removeClass(target[i], 'ex-over');
          
        
       else 
        el.remove();
        this.moveto();
      
      for (let i = 0; i < this.target.length; i++) 
        this.target[i].state = false;
      
      this.challtarget = false;
     else if (source.attributes[2].value === "target" && (target.attributes[3].value === "cd" || target.attributes[2].value === "data")) 
      if (this.target.length < 1) 
        this.placeholdertarget = true;
      
      if (this.data.length > 0) 
        this.placeholderdata = false;
      
      if (!this.hasMultiple) 
        let target = document.getElementsByClassName('data');
        for (let i = target.length - 1; i >= 0; i--) 
          if (target[i].className.includes('ex-over') && i >= 0) 
            this.removeClass(target[i], 'ex-over');
          
        
       else 
        el.remove();
        this.moveback();
      
      for (let i = 0; i < this.data.length; i++) 
        this.data[i].state = false;
      
      this.challdata = false;
     else 
      // console.log('spilled');
      // this.dragulaService.find('dnd').drake.cancel(true);
    
  );

【讨论】:

以上是关于角度多重拖放(ng2-dragula)的主要内容,如果未能解决你的问题,请参考以下文章

ng2-dragula 添加新项目后显示在顶部

Angular 2:如何有条件地应用属性指令?

带布局选项的角度拖放

角度材质嵌套拖放

区分 ng2-dragula 上的单击或拖动

角度拖放(使用 jQuery UI) - 禁用交换