Angular перетаскивание не работает при отбрасывании элементов в n-арном дереве, представленном с использованием рекурсивного шаблона - PullRequest
0 голосов
/ 13 января 2020

Я новичок в angular перетаскивании материала.

Мое приложение использует n-арное дерево, и, поскольку я не знаю его форму apriori, я был вынужден использовать рекурсивный шаблон для его представления.

Последние пару дней я пытался использовать Angular перетаскивание материала для изменения порядка братьев и сестер. Если я удаляю узел root, все работает нормально, но я не могу удалить узел root, так как он нужен мне для обхода дерева для других операций.

Сильфон - это упрощенная форма дерева. На самом деле у дерева может быть гораздо больше ветвей и листьев, но я хотел, чтобы оно было простым.

Json n-арного дерева (root узел с тремя дочерними узлами, которыми я хочу быть возможность перетаскивания):

[
  {
    "orderIndex": 0,
    "id": "5a4f87ce-c52d-4cc1-b587-21898ded5cc0",
    "parentId": "5a4f87ce-c52d-4cc1-b587-21898ded5cc0",
    "name": "Interface1",
    "conditions": "None",
    "text": null,
    "description": "description",
    "children": [
      {
        "orderIndex": 0,
        "id": "5a4f87ce-c527-4cc1-b587-22898ded5cc0",
        "parentId": "5a4f87ce-c52d-4cc1-b587-21898ded5cc0",
        "name": "Interface2",
        "conditions": "None",
        "text": null,
        "description": "description",
        "children": [],
        "errors": null
      },
      {
        "orderIndex": 1,
        "id": "5a4f87ce-c527-4cc8-b587-26898ded5cc0",
        "parentId": "5a4f87ce-c527-4cc8-b587-23898ded5cc0",
        "name": "Interface6",
        "conditions": "None",
        "text": null,
        "description": "description",
        "children": [],
        "errors": null
      },
      {
        "orderIndex": 2,
        "id": "5a4f87ce-c525-4cc1-b587-25898ded5cc0",
        "parentId": "5a4f87ce-c52e-4cc1-b587-24898ded5cc0",
        "name": "Interface4",
        "conditions": "None",
        "text": null,
        "description": "description",
        "children": [],
        "errors": null
      }
    ],
    "errors": null
  }
]

Компонент:

import { DataService } from './../data.service';
import { Node } from '../_Models/Node';
import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';

@Component({
  selector: 'app-vnf-main',
  templateUrl: './vnf-main.component.html',
  styleUrls: ['./vnf-main.component.css']
})
export class VnfMainComponent implements OnInit {
  tree: Node[];

  constructor(private dataService: DataService) {
  }

  ngOnInit() {
    this.dataService.tree$.subscribe(result => {
      this.tree = result;
    });

  drop(event: CdkDragDrop<Node[]>) {
    moveItemInArray(this.tree, event.previousIndex, event.currentIndex);
  }
}

Код шаблона:

<table>
     <ng-template #recursiveList let-tree>
         <div cdkDropList (cdkDropListDropped)="drop($event)">
             <div *ngFor="let node of tree; let i=index " cdkDrag>
                 <tr>
                    <app-default-node [node]="node"></app-default-node>
                    <td *ngIf="node.children!==null && node.children.length > 0" cdkDrag>
                        <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: node.children }"></ng-container>
                    </td>
                 </tr>
             </div>
         </div>
     </ng-template>
</table>
<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: tree }"></ng-container>

Также: Как узнать, что узел перетаскивается и узел, после которого он был удален? Я нигде не смог найти ответ, но если бы я смог получить эти два, я мог бы решить его, пройдя по дереву и выполнив все вручную.

Заранее спасибо и за то, что так далеко и читая весь вопрос.

Ответы [ 2 ]

0 голосов
/ 13 января 2020

В случае, если некоторые сталкиваются с той же проблемой ... Я решил эту проблему, передав узел перетаскиваемым в метод отбрасывания, используя [cdkDragData] = node , поскольку перетаскивание cdk предназначено для списков, не n-арные деревья.

<div [cdkDragData]=node *ngFor="let node of tree; let i=index " cdkDrag>

Затем внутри метода можно пройти по дереву и внести изменения «вручную»:

const movedNode: Node = event.item.data; //Node that was dragged
const parentNode: Node = this.dataService.findNode(movedNode.parentId, this.tree[0]); //parent of the dragged node
moveItemInArray(parentNode.children, event.previousIndex, event.currentIndex); //move the node as in any other cdk drag and drop list

Спасибо за полученные ответы, это действительно побудило меня найти лучшее решение ?

0 голосов
/ 13 января 2020

Вы можете использовать перетаскивание HTML5. Работает нормально с angular2 +. Ссылка Ссылка https://www.w3schools.com/html/html5_draganddrop.asp

...