control component angular2 drag-and-drop tree angularjs

drag-and-drop - component - angularjs treeview checkbox



AngularJS-¿Cómo hacer un árbol arrastrable? (3)

Eche un vistazo a este ejemplo: http://jsfiddle.net/furf/EJGHX/

Acabo de completar esta solución, por lo que aún no está debidamente documentada, pero debería poder extraerla para su solución.

Necesitarás usar algunas cosas:

  1. la directiva ezTree - para renderizar el árbol
  2. Plugin anidado de Manuele J Sarfatti para jQuery UI
  3. (opcional) la directiva uiNestedSortable - para habilitar nestedSortable desde su plantilla.
  4. código del controlador para actualizar su modelo - consulte $scope.update

Usando la directiva ezTree

Dada una estructura de datos recursiva:

$scope.data = { children: [{ text: ''I want to create a tree like structure...'', children: [{ text: ''Take a look at this example...'', children: [] }] }] };

Esta plantilla construirá el árbol:

<ol> <li ez-tree="child in data.children at ol"> <div>{{item.text}}</div> <ol></ol> </li> </ol>

La expresión ez-tree debe escribirse como item in collection at selector donde item es el item iterado (ala ng-repeat ), collection es la colección de nivel raíz, y selector es el selector CSS para el nodo dentro de la plantilla donde la directiva debe recurse. El nombre de la propiedad de la terminal de la colección, en este caso, los children se utilizarán para volver a generar el árbol, en este caso child.children . Esto podría reescribirse para ser configurable, pero lo dejo como un ejercicio para el lector.

Uso de la directiva uiNestedSortable

<ol ui-nested-sortable="{ listType: ''ol'', items: ''li'', doNotClear: true }" ui-nested-sortable-stop="update($event, $ui)"> </ol>

El atributo ui-nested-sortable debe contener una configuración JSON para el complemento anidadoSortable. El complemento requiere que especifique listType y items . Mi solución requiere que doNotClear sea true . Asignar devoluciones de llamadas a eventos usando ui-nested-sortable-*eventName* . Mi directiva proporciona argumentos opcionales de $ event y $ ui para las devoluciones de llamada. Consulte la documentación de nestedSortable para otras opciones.

Actualizando tu modelo

Hay más de una manera de despellejar a este gato. Aquí está el mío. En el evento de detención, extrae la propiedad hija del alcance del elemento para determinar qué objeto se movió, la propiedad secundaria del alcance principal del elemento para determinar el destino del objeto y la posición del elemento para determinar la posición del objeto en su destino A continuación, recorre la estructura de datos y elimina el objeto de su posición original y lo inserta en su nueva posición.

$scope.update = function (event, ui) { var root = event.target, item = ui.item, parent = item.parent(), target = (parent[0] === root) ? $scope.data : parent.scope().child, child = item.scope().child, index = item.index(); target.children || (target.children = []); function walk(target, child) { var children = target.children, i; if (children) { i = children.length; while (i--) { if (children[i] === child) { return children.splice(i, 1); } else { walk(children[i], child) } } } } walk($scope.data, child); target.children.splice(index, 0, child); };

Quiero crear una estructura tipo árbol donde el usuario pueda arrastrar y soltar hojas. Tengo un punto de partida de la siguiente manera:

HTML

<div ng:controller="controller"> <ul ui-sortable ng-model="items" ui-options="{connectWith: ''.item''}" class="item"> <li ng-repeat="item in items" class="item"> {{ item.name }} <ul ui-sortable ng-model="item.children" ui-options="{connectWith: ''.item''}" class="item"> <li ng-repeat="item in item.children" class="item">{{ item.name }}</li> </ul> </li> </ul> <pre>{{ items | json }}</pre> </div> <script src="http://code.angularjs.org/1.0.2/angular.min.js"></script> <script src="https://raw.github.com/angular-ui/angular-ui/master/build/angular-ui.min.js"></script>

CoffeeScript

myapp = angular.module ''myapp'', [''ui''] myapp.controller ''controller'', ($scope) -> $scope.items = [ {id: 1, name: ''Item 1'', children: [ {id: 5, name: ''SubItem 1.1'', children: [ {id: 11, name: ''SubItem 1.1.1'', children: []}, {id: 12, name: ''SubItem 1.1.2'', children: []} ]}, {id: 6, name: ''SubItem 1.2'', children: []} ]}, {id: 2, name: ''Item 2'', children: [ {id: 7, name: ''SubItem 2.1'', children: []}, {id: 8, name: ''SubItem 2.2'', children: []} {id: 9, name: ''SubItem 2.3'', children: []} ]}, {id: 3, name: ''Item 3'', children: [ {id: 10, name: ''SubItem 3.1'', children: []} ]} ] angular.bootstrap document, [''myapp'']

El código también está en este JSFiddle: http://jsfiddle.net/bESrf/1/

En mi código "real", en lugar de tener solo un nivel para niños, extraje el segundo <ul> en una plantilla y lo renderizo recursivamente, lo que funciona bien, pero no pude encontrar una manera de hacerlo en JSFiddle.

¿Cuál sería la mejor manera de renderizarlo de manera recursiva y aún permitir el arrastre y la caída que cambiaría la matriz de objetos y subobjetos representados por ng-model?


Leve edición del violín por furf para que funcione en IE.

IE da un error en insertNode cuando el segundo argumento es nulo, entonces cuando este es el caso, se usa appendNode en su lugar.

http://jsfiddle.net/michieljoris/VmtfR/

if (!cursor) parentNode.appendChild(cached.element); else parentNode.insertBefore(cached.element, cursor);

El complemento ordenado anidado está en línea en el js, porque IE da una discrepancia en el tipo MIME cuando se incluye desde github.