Copying an item rather than moving in the knockout

2019-07-24 08:35发布

问题:

This is the seating chart example of knockout sortable: http://jsfiddle.net/UdXr4/ Based on the answers of this and this, I tried to change the seating chart example such that the items from available students copied rather than moved as in the jsfiddle here

The changes are shown below :

......
......
<div class="seats" data-bind="sortable: { data: students, allowDrop: $root.isTableFull, dragged: handleDraggedItem }">
......
......
<div class="new" data-bind="sortable: availableStudents">
        <div class="student available" data-bind="text: name"></div>
    </div>
.......
.......
Student.prototype.clone = function() {
    return new Student(this.id,this.name(),this.gender);
};
.......
.......
this.handleDraggedItem = function(item, event, ui) {
        console.log("handleDraggedItem");
        **return new Student(0,ui.item.text(),'');**
    };
.......
.......
$(".available").draggable({
    connectToSortable: ".seats",
    helper: "clone",
    start: function(event, ui) {
        ko.utils.domData.set(event.target, "ko_dragItem", true);
    }
});

The code that I'm unable to solve is the handledraggeditem [return new Student(0,ui.item.text(),'')]. How can I get the other values (id and gender) except name(this I'm able to get from text) such that I can send them here..

Due to this the $data for the dragged items have 0 as id and '' as gender as below..

{
          "id": 9,
          "name": "Kylie",
          "gender": "female",
          "group": "griffindor"
        },
        {
          "id": 0,
          "name": "Angel",
          "gender": "",
          "group": ""
        }

Any help is sincerely appreciated

Thanks

回答1:

When the user starts to drag an element, you are currently attaching a value of true to it:

$(".available").draggable({
    connectToSortable: ".seats",
    helper: "clone",
    start: function(event, ui) {
        ko.utils.domData.set(event.target, "ko_dragItem", true); // <---
    }
});

Whatever data you attach there is what the dragged: callback will receive as its first argument — in your case, handleDraggedItem:

this.handleDraggedItem = function(item, event, ui) {
  // 'item' is now 'true'
  console.log("handleDraggedItem");
};

If you instead look up the Student that is bound to the dragged element with ko.dataFor and attach that:

start: function(event, ui) {
  var student = ko.dataFor(event.target);

  ko.utils.domData.set(event.target, "ko_dragItem", student);
}

your handleDraggedItem handler will receive that Student as its first argument, and you can call your Student.prototype.clone method on it:

this.handleDraggedItem = function(item, event, ui) {
  return item.clone();
};