Knockout嵌套可排序列表 [英] Knockout nested sortable lists

查看:69
本文介绍了Knockout嵌套可排序列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要构建一个包含两个可以交换的列表的网页。列表中的项目也可以交换或从一个列表移动到另一个列表。



我使用knockoutjs和knockoutjs-sortable来实现这一点。



HTML

 < ul class =任务数据-bind =sortable:TaskLists> 
< li class =taskList>
< span data-bind =text:Titlestyle ='background:lightgray;'>< / span>
< ul data-bind =sortable:Tasks>
< li class =item>
< span class =taskNamehref =#data-bind =text:name>< / span>
< / li>
< / ul>
< / li>
< / ul>

JS

  var任务=函数(名称){
this.name = ko.observable(name);
}

var ViewModel = function(){
var self = this;
self.tasks1 = ko.observableArray([]);
self.tasks2 = ko.observableArray([]);
for(var i = 0; i< 5; i ++){
self.tasks1.push(new Task(此任务属于列表一));
self.tasks2.push(新任务(此任务属于列表二));
}
self.TaskList1 = {
任务:self.tasks1,
标题:'List One'
};
self.TaskList2 = {
任务:self.tasks2,
标题:'列表2'
};
self.TaskLists = ko.observableArray([]);
self.TaskLists.push(self.TaskList1);
self.TaskLists.push(self.TaskList2);
};

ko.bindingHandlers.sortable.options = {
占位符:'ui-state-highlight',
start:function(e,ui){
var dragElements = $('。ui-state-highlight');
dragElements.css(height,ui.helper.outerHeight());
}
};
ko.applyBindings(new ViewModel());

CSS

  .frame {
padding:10px;
溢出:auto;
}
.item {
border:black 1px solid;
宽度:100px;
background-color:#DDD;
cursor:move;
text-align:center;
margin-top:2px;
margin-bottom:2px;
}
.taskList {
宽度:110px;
float:left;
背景:lightgreen;
}
.Tasks {
宽度:400px;
border:1px #eee solid;
身高:100%;
}
.taskName {
word-wrap:break-word;
}
.ui-state-highlight {
background:grey;
border:1px灰色;
}

这是我到目前为止所得到的显示完整的工作解决方案。



HTML

 < div class =frame> 
< ul class =Tasksdata-bind =sortable:{data:TaskLists,connectClass:'columns',options:{placeholder:'list-highlight'}}>
< li class =taskList>
< span data-bind =text:Titlestyle ='background:lightgray;'>< / span>
< ul data-bind =sortable:{data:Tasks,connectClass:'columnItems',options:{placeholder:'ui-state-highlight'}}>
< li class =item>
< span class =taskNamehref =#data-bind =text:name>< / span>
< / li>
< / ul>
< / li>
< / ul>
< / div>

JS

  var任务=函数(名称){
this.name = ko.observable(name);
}

var ViewModel = function(){
var self = this;
self.tasks1 = ko.observableArray([]);
self.tasks2 = ko.observableArray([]);
for(var i = 0; i< 5; i ++){
self.tasks1.push(new Task(此任务属于列表一));
self.tasks2.push(新任务(此任务属于列表二));
}
self.TaskList1 = {任务:self.tasks1,标题:'列表一'};
self.TaskList2 = {Tasks:self.tasks2,Title:'List Two'};
self.TaskLists = ko.observableArray([]);
self.TaskLists.push(self.TaskList1);
self.TaskLists.push(self.TaskList2);
};

ko.bindingHandlers.sortable.options = {
//占位符:'ui-state-highlight',
start:function(e,ui){
var dragItems = $('。ui-state-highlight');
var dragLists = $('。list-highlight');
var elementClass = ui.helper [0] .className;
if(elementClass ===item)
dragItems.css(height,ui.helper.outerHeight());
if(elementClass ===taskList)
dragLists.css(height,ui.helper.outerHeight());
}
};
ko.applyBindings(new ViewModel());

CSS

  .frame {
padding:10px;
溢出:auto;
}

.item {
border:black 1px solid;
宽度:100px;
background-color:#DDD;
cursor:move;
text-align:center;
margin-top:2px;
margin-bottom:2px;
}

.list-highlight {
宽度:100px;
float:left;
背景:灰色;
}

.taskList {
宽度:110px;
float:left;
背景:lightgreen;
}

.Tasks {
宽度:400px;
border:1px #eee solid;
身高:100%;
}

.taskName {
word-wrap:break-word;
}

.ui-state-highlight {
background:grey;
border:1px灰色;
}


I need to build a web page that has two lists that can be swapped around. The lists have items that can also be swapped or moved from one list to the other.

I used knockoutjs and knockoutjs-sortable to implement this.

HTML

<ul class="Tasks" data-bind="sortable: TaskLists">
    <li class="taskList"> 
        <span data-bind="text: Title" style='background: lightgray;'></span>
        <ul data-bind="sortable: Tasks">
           <li class="item"> 
              <span class="taskName" href="#" data-bind="text: name"></span>
            </li>
        </ul>
    </li>
</ul>

JS

var Task = function (name) {
    this.name = ko.observable(name);
}

var ViewModel = function () {
    var self = this;
    self.tasks1 = ko.observableArray([]);
    self.tasks2 = ko.observableArray([]);
    for (var i = 0; i < 5; i++) {
        self.tasks1.push(new Task("This task belongs to list one"));
        self.tasks2.push(new Task("This task belongs to list two"));
    }
    self.TaskList1 = {
        Tasks: self.tasks1,
        Title: 'List One'
    };
    self.TaskList2 = {
        Tasks: self.tasks2,
        Title: 'List Two'
    };
    self.TaskLists = ko.observableArray([]);
    self.TaskLists.push(self.TaskList1);
    self.TaskLists.push(self.TaskList2);
};

ko.bindingHandlers.sortable.options = {
    placeholder: 'ui-state-highlight',
    start: function (e, ui) {
        var dragElements = $('.ui-state-highlight');
        dragElements.css("height", ui.helper.outerHeight());
    }
};
ko.applyBindings(new ViewModel());

CSS

.frame {
    padding: 10px;
    overflow:auto;
}
.item {
    border: black 1px solid;
    width: 100px;
    background-color: #DDD;
    cursor: move;
    text-align: center;
    margin-top: 2px;
    margin-bottom: 2px;
}
.taskList {
    width: 110px;
    float:left;
    background: lightgreen;
}
.Tasks {
    width:400px;
    border: 1px #eee solid;
    height: 100%;
}
.taskName {
    word-wrap: break-word;
}
.ui-state-highlight {
    background: grey;
    border:1px dashed grey;
}

Here is what I got so far (fiddle).

All is working as expected except moving the lists around. When moving a list around, I expect the drag-gable placeholder to look like:

but I get is:

What am I doing wrong? How can I achieve these expected results?

解决方案

I found the problem after a good night sleep. There was several pitfalls in my design above:

  • The nested lists did not have a connectClass that will help knockout-sortable find out where the element can be dragged. Leaving this unspecified makes one of the lists accept either an item or a complete list to be dragged into it.
  • The draggable place holder has a different styling that the lists themselves. This is why the draggable placeholder was not correctly rendered (ref. the resulted screenshot in my question above)
  • There was only one place holder defined, that applied to both a dragged item and a dragged list which is not good.

Here is a fiddle showing the full working solution.

HTML

<div class="frame">
    <ul class="Tasks" data-bind="sortable: {data: TaskLists, connectClass: 'columns', options: { placeholder: 'list-highlight'}}">
      <li class="taskList">
        <span data-bind="text: Title" style='background: lightgray;'></span>
        <ul data-bind="sortable: {data: Tasks, connectClass: 'columnItems', options : { placeholder: 'ui-state-highlight'}}">
            <li class="item">
              <span class="taskName" href="#" data-bind="text: name"></span>
            </li>
        </ul>
       </li>
    </ul>
</div>

JS

var Task = function(name) {
    this.name = ko.observable(name);
}

var ViewModel = function() {
    var self = this;
    self.tasks1 = ko.observableArray([]);
    self.tasks2 = ko.observableArray([]);
    for (var i=0;i<5;i++){ 
        self.tasks1.push(new Task("This task belongs to list one"));
        self.tasks2.push(new Task("This task belongs to list two"));
    }
    self.TaskList1 = {Tasks: self.tasks1, Title:'List One'};
    self.TaskList2 = {Tasks: self.tasks2, Title:'List Two'};
    self.TaskLists = ko.observableArray([]);
    self.TaskLists.push(self.TaskList1);
    self.TaskLists.push(self.TaskList2);
};

ko.bindingHandlers.sortable.options = {
        //placeholder: 'ui-state-highlight',
        start: function (e, ui) {
            var dragItems = $('.ui-state-highlight');
            var dragLists = $('.list-highlight');
            var elementClass = ui.helper[0].className;
            if(elementClass === "item")
                  dragItems.css("height",ui.helper.outerHeight());
            if(elementClass === "taskList")
                  dragLists.css("height",ui.helper.outerHeight());
        }
    };
ko.applyBindings(new ViewModel());

CSS

    .frame{
        padding: 10px;
        overflow:auto;
    }

    .item {
       border: black 1px solid;
       width: 100px;
       background-color: #DDD;
       cursor: move;
       text-align: center;
       margin-top: 2px;
       margin-bottom: 2px;
    }

    .list-highlight{
        width: 100px;
        float:left;
        background: gray;
    }

    .taskList{
        width: 110px;
        float:left;
        background: lightgreen;
    }

    .Tasks{
        width:400px;
        border: 1px #eee solid;
        height: 100%;
    }

    .taskName{
        word-wrap: break-word;
    }

    .ui-state-highlight{
        background: grey;
        border:1px dashed grey;
}

这篇关于Knockout嵌套可排序列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆