2014-09-25 89 views
1

我想创建一个简单的方法来定义组的列表。这些组包括ID,说明,启用/禁用字段和排序顺序。我正在尝试使用KendoUI可排序小部件。我遇到的问题时,当我:从淘汰赛observablearray删除新项目不更新kendo排序

  1. 添加一个新的项目
  2. 向上移动项目列表中的
  3. 尝试从列表

该项目被删除删除项目从可观察的数组中,但仍然显示在可排序的小部件中。

我试图尽可能简化代码来证明问题。

//-------------------------------------------------------------------------------------------------- 
 
// MenuGroup View Models 
 
//-------------------------------------------------------------------------------------------------- 
 
function MenuGroup() { 
 
    var self = this; 
 
    self.MenuGroupId = ko.observable(0); 
 
    self.Description = ko.observable(""); 
 
    self.DisplayOrder = ko.observable(0); 
 
    self.MenuActive = ko.observable(true); 
 
} 
 

 
var menuGroupMapping = { 
 
    MenuGroup: { 
 
    key: function(group) { 
 
     return ko.utils.unwrapObservable(group.MenuGroupId); 
 
    }, 
 
    create: function(group) { 
 
     var groupObj = ko.mapping.fromJS(group); 
 
     return groupObj; 
 
    } 
 
    } 
 
} 
 

 
function MenuGroupsViewModel() { 
 
    var self = this; 
 

 
    self.baseUri = "/api/menugroups"; 
 
    self.menugroups = ko.observableArray(); 
 
    self.newMenuGroup = ko.observable(new MenuGroup()); 
 
    self.selectedGroup = ko.observable(new MenuGroup()); 
 

 
    self.save = function(formElement) { 
 
    self.newMenuGroup().DisplayOrder(self.menugroups().length); 
 
    self.menugroups.push(self.newMenuGroup()); 
 
    var g = new MenuGroup(); 
 
    self.newMenuGroup(g); 
 
    }; 
 

 
    self.deleteGroup = function(group) { 
 
    bootbox.confirm("Are you sure you want to delete the following menu group: " + group.Description(), function(result) { 
 
     self.menugroups.remove(group); 
 
    }); 
 
    } 
 

 
    self.selectGroup = function(group) { 
 
    self.selectedGroup(group); 
 
    }; 
 

 
    self.changeOrder = function(oldPosition, newPosition) { 
 
    var movedGroup = self.menugroups()[oldPosition]; 
 
    movedGroup.DisplayOrder(newPosition); 
 
    var id = movedGroup.MenuGroupId(); 
 

 
    ko.utils.arrayForEach(self.menugroups(), function(menugroup) { 
 
     if (oldPosition < newPosition) { 
 
     if (oldPosition <= menugroup.DisplayOrder() && newPosition >= menugroup.DisplayOrder() && menugroup.MenuGroupId() != id) { 
 
      menugroup.DisplayOrder(menugroup.DisplayOrder() - 1); 
 
     } 
 
     } else { 
 
     if (oldPosition >= menugroup.DisplayOrder() && newPosition <= menugroup.DisplayOrder() && menugroup.MenuGroupId() != id) { 
 
      menugroup.DisplayOrder(menugroup.DisplayOrder() + 1); 
 
     } 
 
     } 
 
    }); 
 

 
    self.menugroups().splice(oldPosition, 1); 
 
    self.menugroups().splice(newPosition, 0, movedGroup); 
 
    } 
 

 
    var data = [{ 
 
    "MenuGroupId": 0, 
 
    "Description": "Group A", 
 
    "DisplayOrder": 0, 
 
    "MenuActive": true 
 
    }, { 
 
    "MenuGroupId": 1, 
 
    "Description": "Group B", 
 
    "DisplayOrder": 1, 
 
    "MenuActive": false 
 
    }, { 
 
    "MenuGroupId": 2, 
 
    "Description": "Group C", 
 
    "DisplayOrder": 2, 
 
    "MenuActive": true 
 
    }, { 
 
    "MenuGroupId": 3, 
 
    "Description": "Group D", 
 
    "DisplayOrder": 3, 
 
    "MenuActive": true 
 
    }] 
 
    ko.mapping.fromJS(data, menuGroupMapping, self.menugroups); 
 
} 
 

 

 
//-------------------------------------------------------------------------------------------------- 
 
// Custom Bindings 
 
//-------------------------------------------------------------------------------------------------- 
 
ko.bindingHandlers.showModal = { 
 
    init: function(element, valueAccessor) {}, 
 
    update: function(element, valueAccessor) { 
 
    var value = valueAccessor(); 
 
    if (ko.utils.unwrapObservable(value)) { 
 
     $(element).modal('show'); 
 
     $("input", element).focus(); 
 
    } else { 
 
     $(element).modal('hide'); 
 
    } 
 
    } 
 
} 
 

 

 

 
mg = new MenuGroupsViewModel(); 
 

 
ko.applyBindings(mg, document.getElementById('menu-group-panel')); 
 

 

 
$(document).ready(function() { 
 
    $("#menu-list").kendoSortable({ 
 
    handler: ".menu-group-handle", 
 
    hint: function(element) { 
 
     return element.clone().addClass("hint"); 
 
    }, 
 
    placeholder: function(element) { 
 
     return element.clone().css({ 
 
     "opacity": 0.3, 
 
     "border": "1px dashed #000000" 
 
     }); 
 
    }, 
 
    axis: "y", 
 
    container: "#menu-list", 
 
    cursor: "move", 
 
    change: onChange 
 
    }); 
 
}); 
 

 
function onChange(e) { 
 
    mg.changeOrder(e.oldIndex, e.newIndex); 
 
}
body { 
 
    padding: 20px; 
 
} 
 
.def-panel { 
 
    height: 100%; 
 
    margin: 0 30px 0 0; 
 
    width: 300px; 
 
    float: left; 
 
} 
 
#menu-list { 
 
    padding: 0; 
 
    width: 200px; 
 
} 
 
.menu-group-handle { 
 
    width: 30px; 
 
    height: 50px; 
 
    display: inline-block; 
 
    background-color: darkslategray; 
 
} 
 
div.menu-group { 
 
    display: inline-block; 
 
    width: 200px; 
 
    height: 50px; 
 
    background-color: aliceblue; 
 
    font-family: "Segoe Ui", Helvetica, Arial, 'DejaVu Sans', 'Liberation Sans', Freesans, sans-serif; 
 
    margin: 5px 0; 
 
    padding: 0; 
 
    cursor: pointer; 
 
} 
 
.menu-group-desc { 
 
    font-weight: 700; 
 
    margin: 10px; 
 
} 
 
.menu-group-selected { 
 
    background-color: darkslateblue !important; 
 
    color: white; 
 
}
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet"/> 
 
    <script src="//code.jquery.com/jquery-1.9.1.min.js"></script> 
 
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> 
 
    <script src="//cdn.kendostatic.com/2014.2.903/js/kendo.all.min.js"></script> 
 
    <h2>Group/Item Definitions</h2> 
 

 
    <div id="menu-canvas"> 
 
    <div id="menu-group-panel" class="def-panel"> 
 
     <h3>Menu Groups</h3> 
 
     <div id="menu-list" data-bind="foreach: menugroups"> 
 
     <div class="menu-group" data-bind="click: function() { mg.selectGroup($data) }, css: {'menu-group-selected': $parent.selectedGroup().MenuGroupId === $data.MenuGroupId}"> 
 
      <span class=" menu-group-handle"> 
 
\t \t \t \t \t \t &nbsp; 
 
\t \t \t \t \t </span> 
 
      <!--<span data-bind="click: function() { mg.selectGroup($data) }, css: {'menu-group-selected': $parent.selectedGroup().MenuGroupId === $data.MenuGroupId}" class="menu-group"> 
 
\t \t \t \t \t --> 
 
      <span class="menu-group"> 
 
\t \t \t \t \t \t <button class="close menu-group-delete" data-bind="click: function() { mg.deleteGroup($data) } ">&times;</button> 
 
\t \t \t \t \t \t <span class="menu-group-desc" data-bind="text: $data.Description"></span> 
 
      <span data-bind="text: $data.DisplayOrder"></span> 
 
      </span> 
 
     </div> 
 
     </div> 
 

 
     <div class="menu-list"> 
 
     <button data-toggle="modal" data-target="#new-menu-group">New menu group...</button> 
 
     </div> 
 

 
     <div style="width: 800px;" data-bind="foreach: menugroups"> 
 
     <span data-bind="text: $data.DisplayOrder"></span>-<span data-bind="text: $data.Description"></span>, 
 
     </div> 
 
     <div class="modal fade" data-bind="with: newMenuGroup" id="new-menu-group"> 
 
     <div class="modal-dialog"> 
 
      <div class="modal-content"> 
 
      <div class="modal-header"> 
 
       <button class="close" data-dismiss="modal">&times;</button> 
 
       <h3>New Menu Group</h3> 
 
      </div> 
 
      <div class="modal-body"> 
 
       <form class="form-horizontal" id="add-menugroup" data-bind="submit: $parent.save"> 
 
       <fieldset> 
 
        <div class="form-group"> 
 
        <label class="control-label col-sm-2">Group Name</label> 
 
        <div class="col-sm-10"> 
 
         <input class="form-control" data-bind="value: Description" type="text" id="menu-group-name" /> 
 
        </div> 
 
        </div> 
 

 
        <div class="form-group"> 
 
        <div class="col-sm-10 col-sm-push-2"> 
 
         <div class="checkbox"> 
 
         <input data-bind="checked: MenuActive" type="checkbox" /> 
 
         <label>Menu group is active</label> 
 
         </div> 
 
        </div> 
 
        </div> 
 
       </fieldset> 
 
       </form> 
 
      </div> 
 
      <div class="modal-footer"> 
 
       <a href="#" class="btn btn-primary" data-bind="click: $parent.save" data-dismiss="modal">Save Changes</a> 
 
       <a href="#" class="btn" data-dismiss="modal">Close</a> 
 
      </div> 
 
      </div> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    </div> 
 

 
    <script src="//ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.debug.js"></script> 
 
    <script src="//cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.3.0/bootbox.min.js"></script> 
 
    <script src="//ajax.aspnetcdn.com/ajax/jquery.ui/1.10.4/jquery-ui.js"></script> 
 
    <script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>

回答

0

下面的代码添加到您的MenuGroupsViewModel:

self.refresh = function() { 
     var tempArray = self.menugroups().slice(0); 
     self.menugroups([]); 
     self.menugroups(tempArray); 
    }; 

然后在self.deleteGroup功能添加下面一行在函数的末尾:

self.refresh(); 

这将强制observableArray刷新。