使用primeng p-tree组件停止节点drop事件

时间:2017-07-27 08:16:36

标签: angular tree primeng

我正在使用primeng p-tree组件,我想禁止某些节点类型放入另一个节点类型。

例如,我有类型文件夹的节点和另一个类型文件的节点,我只希望类型文件的节点在类型文件夹的节点内移动。我想禁止在另一个文件夹节点内移动文件夹节点。 (和其他规则

<p-tree [value]="filesTree7" draggableNodes="true" droppableNodes="true" dragdropScope="files" selectionMode="single" [(selection)]="selectedFile2" [contextMenu]="cm" (contextmenu)="onContextMenu($event)"
          (onNodeDrop)="onNodeDrop($event)"></p-tree> 

我试图像这样停止传播:

onNodeDrop(event) {
    console.log("onNodeDrop");
    event.originalEvent.stopPropagation();
    event.originalEvent.preventDefault();
    return;
}

但它不起作用。

当我在这里查看primeng代码时:primeng tree component code source似乎 onNodeDrop 事件发出得太晚。

你有什么想法可以实现我需要的东西吗?

3 个答案:

答案 0 :(得分:2)

在实现this之前,解决方法可能是覆盖allowDrop组件的Tree method并编写自己的放置逻辑实现。 但是,您可能(实际上您应该)想要使用原始方法中介绍的放置逻辑,而只需添加您的位。

现在prototyping可能看起来像这样:

  • 在您使用过pTree的组件中,通过Tree获得ViewChild

    @ViewChild(Tree) tree: Tree;
    
  • 然后在constructorngOnInit或任何适合您的情况下,prototype allowDrop

    Tree.prototype.allowDrop = (dragNode: any, dropNode: any, dragNodeScope: any): boolean => {
      return this._overrideAllowDrop(dragNode, dropNode, dragNodeScope)
    }
    

_overrideAllowDrop用于简洁起见。要取消删除,只需return false

此外,在删除失败的情况下,您可以利用树实例的dragDropService来显示错误消息。

例如:

this.tree.dragDropService.dragStop$.subscribe((data) => {
  if(this.failed){ // set failed to true in your custom drop logic
    alert('Error!')
  }
})

但是这种解决方法的缺点是放置逻辑应该在UI端,并且如果您的逻辑需要后端干扰,那么这种解决方法可能没有太大帮助。

尽管在我的案例中涉及了后端,但是逻辑很简单,所以我将其移至UI端,因此prototyping达到了目的。

答案 1 :(得分:0)

如果您希望单个节点不可插入或可拖动,则必须在数组中设置params draggable / droppable:

{
    "label": "Note e Commenti",
    "icon": "fa-file-word-o",
    "draggable":false,
    "droppable":false,
    "data": {
        "id": 1,
        "nome": "Note e Commenti",
        "testo": "Note e Commenti",
        "idCategoria": 2,
        "idTipologia": 1
    }
},

答案 2 :(得分:0)

这里有一些重要的额外细节,尤其是 bind() 函数

    export class myClass implements AfterViewInit {
      @ViewChild('primeTree') primeTree: Tree;  // named in HTML
    
      ngAfterViewInit() {
        // get the original function AND bind it to the tree - important!
        const originalAllowDrop = this.primeTree.allowDrop.bind(this.primeTree);
        
        // replace the allowDrop function with this
        this.primeTree.allowDrop = (dragNode: TreeNode, dropNode: TreeNode, dragNodeScope: any): boolean => {
          // let the original function do the pre-check, and then check for special cases
          return originalAllowDrop(dragNode, dropNode, dragNodeScope) && this.allowDrop(dragNode, dropNode, dragNodeScope);
        }

  }

  private allowDrop(dragNode: TreeNode, dropNode: TreeNode, dragNodeScope: any): boolean {
    // your logic here
    if (imNotHappy) {
      return false
    }
    return true;
  }
}