敲除的可观察数组排序问题

托尼

我在使用引导程序面板组作为手风琴时显示可观察数组时遇到问题,但是当显示为无序列表时,相同的列表正确显示,按 SortOrder 值排序。排序按钮用于模拟从服务器返回的数据,无需手动对任何面板进行排序,您可以按下此按钮,两个列表都会按预期更新。一旦您手动对面板进行排序,按下排序按钮后面板将不再正确排序,但无序列表会继续正确排序。

关于我做错了什么导致手动排序后引导面板无法正确显示的任何建议?

$(function() {
  ko.applyBindings(new schedulerViewModel(new ViewModel()));
});

function Group(id, sortOrder, name) {
  var self = this;
  self.id = ko.observable(id);
  self.sortOrder = ko.observable(sortOrder);
  self.name = ko.observable(name);
};

function ViewModel() {
  var self = this;

  self.groups = ko.observableArray([
    new Group(3, 0, 'System Group'),
    new Group(27, 1, 'New Group Added'),
    new Group(1, 2, 'Group A'),
    new Group(2, 3, 'Group B')
  ]);
};
ko.bindingHandlers.uiSortableList = {
  init: function(element, valueAccessor, allBindingAccessor, context) {
    var $element = $(element),
      list = valueAccessor();
    $element.sortable({
      axis: 'y',
      handle: '#panel-handle',
      stop: function(event, ui) {
        var newIdOrder = $(this).sortable('toArray');
        context.updateWorkgroupsSortOrder(newIdOrder);
        context.sortWorkgroups();
      }
    });
  }
};

function schedulerViewModel(viewModel) {
  var self = this;
  self.comments = ko.observableArray([]);
  self.workgroups = ko.observableArray(viewModel.groups());
  self.sortWorkgroups = function() {
    self.workgroups.sort(function(a, b) {
      var aSortOrder = a.sortOrder(),
        bSortOrder = b.sortOrder(),
        result = 0;
      result = parseInt(aSortOrder) - parseInt(bSortOrder);
      return result;
    });
  };
  self.count = ko.observable(0);
  self.sortButton = function() {
    var array;
    self.count(Math.floor((Math.random() * 10)));
    if (self.count() == 0) {
      array = [27, 2, 3, 1];
    } else if (self.count() == 1) {
      array = [3, 27, 1, 2];
    } else if (self.count() == 2) {
      array = [1, 3, 2, 27];
    } else if (self.count() == 3) {
      array = [3, 2, 27, 1];
    } else if (self.count() == 4) {
      array = [2, 1, 27, 3];
    } else if (self.count() == 5) {
      array = [1, 27, 3, 2];
    } else if (self.count() == 6) {
      array = [2, 3, 1, 27];
    } else if (self.count() == 7) {
      array = [27, 1, 3, 2];
    } else if (self.count() == 8) {
      array = [3, 1, 27, 2];
    } else if (self.count() == 9) {
      array = [1, 2, 27, 3];
    } else {
      array = [27, 3, 2, 1];
    }
    self.updateWorkgroupsSortOrder(array);
    self.sortWorkgroups();
  };
  self.updateWorkgroupsSortOrder = function(workgroupIds) {
    self.comments.push(workgroupIds);
    for (var i = 0; i < workgroupIds.length; i++) {
      var id = workgroupIds[i];
      var workgroup = ko.utils.arrayFirst(this.workgroups(), function(item) {
        return item.id() == id;
      });
      workgroup.sortOrder(i);
    }
  };
};
#panel-handle{
    float:left;
    clear:both;
    position:relative;
    display:inline-block;
    top:0;
    left:0;
    color:gray;
    height: 37px;
    background-color:#f5f5f5;
    -webkit-border-radius:3px;
    -moz-border-radius:3px;
    border-radius:3px;
    border-right:solid 1px #ddd;
    cursor:move;
    margin-right:8px;
}
#panel-handle i{
    padding: 11px 4px;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>



<div>
  <button type="button" data-bind="click: sortButton">Sort (<span data-bind="text: count"></span>)</button>
</div>
<ul data-bind="foreach: workgroups, uiSortableList: workgroups">
  <li><span data-bind="text: name() + ' - '"></span><span data-bind="text: sortOrder()"></span></li>
</ul>
<div id="content" class="col-xs-9 col-md-10">
  <div class="panel-group" id="accordion" data-bind="foreach: workgroups, uiSortableList: workgroups">
    <div data-bind="attr:{id: id() }" class="panel panel-default">
      <span id="panel-handle">
                <i class="fa fa-angle-double-right" aria-hidden="true"></i>
            </span>
      <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-bind="attr:{href: '#work-group-' + id()}">
        <h4 class="panel-title">
                    <span data-bind="text: name()"></span>
                    <span data-bind="text: '(Id) ' + id()"></span>
                    <span data-bind="text: ' - (SortOrder) ' + sortOrder()"></span>
                </h4>
      </div>
    </div>
  </div>
  <div data-bind="foreach: comments, visible: comments().length > 0">
    <div><span data-bind="text: $data"></span></div>
  </div>
</div>

托尼

解决方案是修改 sortable stop 方法如下:

stop: function(event, ui) {
    var item = ko.dataFor(ui.item[0]);
    var position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
    if (position >= 0) {
        list.remove(item);
        ui.item.remove();
        list.splice(position, 0, item);
    }
    var newIdOrder = $(this).sortable('toArray');
    context.updateWorkgroupsSortOrder(newIdOrder);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章