2

Ниже показано дерево, отображаемое как nestedSortable с использованием template в KnockoutJS.KnockoutJS: проверка того, были ли переупорядочены элементы в вложенной сортировке

До сих пор у меня есть дерево, которое работает, но я не смог найти эффективный способ проверить изменения, вызванные перетаскиванием мышью.

Решение должно позволять проверять события изменений всякий раз, когда перетаскивается узел (отслеживание изменений необходимо для сохранения или обновления данных). Он должен иметь возможность определить, что было изменено в дереве.

Признаки интереса будут id перемещенного узла, id нового (и оригинального) родителя.

Как правильно контролировать события мыши, такие как перетаскивание мышью с этим типом сортировки?

function Node(data) { 
 
    var self = this; 
 
    typeof data != 'undefined' ? self.id = data.id : self.id = '1'; 
 
    self.parent = ko.observable(); 
 
    self.children = ko.observableArray(); 
 
    self.addNode = function() { 
 
    var child = new Node({ 
 
     'id': self.id + '.' + (self.children().length + 1) 
 
    }); 
 
    child.parent(self); 
 
    self.children.push(child); 
 
    return child; 
 
    } 
 
}; 
 
var tree = new Node(); 
 
var child1 = tree.addNode(); 
 
var child11 = child1.addNode(); 
 
var child12 = child1.addNode(); 
 
var child2 = tree.addNode(); 
 
var child21 = child2.addNode(); 
 
var child3 = tree.addNode(); 
 
var viewModel = function() { 
 
    this.tree = ko.observable(tree); 
 
}; 
 
ko.applyBindings(new viewModel()); 
 

 
$('.sortable') 
 
    .nestedSortable({ 
 
    startCollapsed: false 
 
    });
ol.sortable, 
 
ol.sortable ol { 
 
    margin: 0 0 0 25px; 
 
    padding: 0; 
 
    list-style-type: none; 
 
} 
 
ol.sortable { 
 
    margin: 4em 0; 
 
} 
 
.sortable li { 
 
    margin: 5px 0 0 0; 
 
    padding: 0; 
 
} 
 
.sortable li div { 
 
    border: 1px solid #d4d4d4; 
 
    cursor: move; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script> 
 
<script src="https://cdn.rawgit.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script> 
 
<script src="https://cdn.rawgit.com/mjsarfatti/nestedSortable/master/jquery.mjs.nestedSortable.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<div class="dd" data-bind="template: {name:'nodeTemplate', data: tree}"></div> 
 
<script id='nodeTemplate' type='text/html'> 
 
    <div data-bind="text: id"></div> 
 
    </div> 
 
    <ol class="sortable ui-sortable" data-bind="foreach: { data: children, as: 'child' }"> 
 
    <li data-bind="template: {name:'nodeTemplate', data: child}, attr: { 'data-id': child.id }"> 
 
    </li> 
 
    </ol> 
 
</script>

+0

Woa, у вас есть * много * вещей происходит в вашем коде/мы должны пройти через много кода, чтобы увидеть, что происходит. Можете ли вы обрезать его до повторного воспроизведения, чтобы он был минимальным для одного вопроса? – Jeroen

+0

Я делаю именно это, некоторые части по-прежнему можно обрезать –

+0

У вас есть около 30 строк css, я бы рискнул предположить, что около 90% из них не нужны, чтобы продемонстрировать проблему. Я также предлагаю удалить зависимости, которые не имеют отношения к делу (например, bootstrap). И т.д. – Jeroen

ответ

1

Это просто направление. Вы можете использовать события «родителя» Sortable Widget.

Может быть, "stop" Событие сортируемого виджета поможет вам?

var size = 5; 
 
var navigationItems = {}; 
 
navigationItems['id'] = 'list_' + (i + 1); 
 
navigationItems['displayLabel'] = 'list_' + (i + 1); 
 
navigationItems['children'] = new Array(size); 
 
for (var i = 0; i < size; i++) { 
 
    navigationItems['children'][i] = {}; 
 
    navigationItems['children'][i]['id'] = 'list_' + (i + 1) + ".1"; 
 
    navigationItems['children'][i]['displayLabel'] = 'list_' + (i + 1) + ".1"; 
 
    navigationItems['children'][i]['children'] = new Array(1); 
 
    navigationItems['children'][i]['children'][0] = {}; 
 
    navigationItems['children'][i]['children'][0]['id'] = 'list_' + (i + 1) + ".1.1"; 
 
    navigationItems['children'][i]['children'][0]['displayLabel'] = 'list_' + (i + 1) + ".1.1"; 
 
    navigationItems['children'][i]['children'][0]['children'] = new Array(0); 
 
}; 
 
var viewModel = function() { 
 
    this.tree = ko.observable(); 
 
}; 
 
var viewModelInstance = new viewModel(); 
 
viewModelInstance.tree(navigationItems); 
 
ko.applyBindings(viewModelInstance); 
 

 
var stopHandler = function(args) { 
 
    var model = ko.dataFor(args.target); 
 
    alert(model.id); 
 
}; 
 
$('.sortable') 
 
    .nestedSortable({ 
 
    startCollapsed: false, 
 
    stop: stopHandler 
 
    });
ol.sortable, 
 
ol.sortable ol { 
 
    margin: 0 0 0 25px; 
 
    padding: 0; 
 
    list-style-type: none; 
 
} 
 
ol.sortable { 
 
    margin: 4em 0; 
 
} 
 
.sortable li { 
 
    margin: 5px 0 0 0; 
 
    padding: 0; 
 
} 
 
.sortable li div { 
 
    border: 1px solid #d4d4d4; 
 
    cursor: move; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script> 
 
<script src="https://cdn.rawgit.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script> 
 
<script src="https://cdn.rawgit.com/mjsarfatti/nestedSortable/master/jquery.mjs.nestedSortable.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<div class="dd" data-bind="template: {name:'nodeTemplate', data: tree}"></div> 
 
<script id='nodeTemplate' type='text/html'> 
 
    <div data-bind="text: displayLabel"></div> 
 
    </div> 
 
    <ol class="sortable ui-sortable" data-bind="foreach: { data: children, as: 'child' }"> 
 
    <!-- ko if: child.children.length > 0 --> 
 
    <li class="mjs-nestedSortable-expanded mjs-nestedSortable-branch" data-bind="template: {name:'nodeTemplate', data: child}, attr: { 'data-id': child.id }"> 
 
    </li> 
 
    <!-- /ko --> 
 
    <!-- ko if: child.children.length == 0 --> 
 
    <li class="mjs-nestedSortable-leaf" data-bind="template: {name:'nodeTemplate', data: child}, attr: { 'data-id': child.id }"> 
 
    </li> 
 
    <!-- /ko --> 
 
    </ol> 
 
</script>

+0

Это было бы частью решения, я должен проверить, предоставили ли данные события достаточную информацию, чтобы пометить его как решение. –

+0

Надеюсь, это поможет. – TSV