首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >KnockoutJS:在添加子级时使嵌套可排序自动展开

KnockoutJS:在添加子级时使嵌套可排序自动展开
EN

Stack Overflow用户
提问于 2015-12-22 20:56:06
回答 1查看 463关注 0票数 0

在所附的示例中,我有一个嵌套的排序器,它能够显示树结构。

目标是在添加新的子元素时使结构展开,以使更改可见。

函数在添加新项时会自动扩展结构,但它只在添加第二个子之后才展开,应该在添加第一个子项后立即展开。

模板可能有问题,或者简单的jQuery+CSS技巧可以解决问题,但我找不到合适的。

代码语言:javascript
复制
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 child2 = tree.addNode();
var viewModel = function() {
  this.tree = ko.observable(tree);
  this.addChild = function(node, event) {
    var self = this;
    node.addNode()
    var $parent = $(event.target).parent().parent();
    if ($parent.prop('tagName') == 'LI') {
      if (!$parent
        .hasClass('mjs-nestedSortable-expanded')) {
        $parent
          .addClass('mjs-nestedSortable-expanded');
      }
      if ($parent
        .hasClass('mjs-nestedSortable-collapsed')) {
        $parent
          .removeClass('mjs-nestedSortable-collapsed');
      }

    }
  }
};
ko.applyBindings(new viewModel());

$('.sortable')
  .nestedSortable({
    startCollapsed: true
  });
代码语言:javascript
复制
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;
}
.sortable .disclose {
  cursor: pointer;
  width: 10px;
  display: none;
}
.sortable li.mjs-nestedSortable-collapsed>ol {
  display: none;
}
.sortable li.mjs-nestedSortable-branch>div>.disclose {
  display: inline-block;
}
.sortable li.mjs-nestedSortable-collapsed>div>.disclose>span:before {
  content: '+ ';
}
.sortable li.mjs-nestedSortable-expanded>div>.disclose>span:before {
  content: '- ';
}
代码语言:javascript
复制
<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>
    <span class="disclose"><span></span></span>
    <span data-bind="text: id"></span>
    <a href="" data-bind="click: $root.addChild">Add child</a>
  </div>
  <ol class="sortable ui-sortable" data-bind="foreach: { data: children, as: 'child' }">
    <!-- ko if: child.children().length > 0 -->
    <li class="mjs-nestedSortable-collapsed 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>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-23 00:59:13

我不知道为什么,但是在AddChild的第一次调用中,您将失去对父元素的引用。您可以替换knockout代码:

代码语言:javascript
复制
var $parent = $(event.target).parent().parent();

若要jQuery解决方案,请执行以下操作:

代码语言:javascript
复制
var $parent = $('.dd').find('*').filter(function() {
    return $(this).text() === node.id;
}).parent().parent();

修改后的片段:

代码语言:javascript
复制
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 child2 = tree.addNode();
var viewModel = function() {
  this.tree = ko.observable(tree);
  this.addChild = function(node, event) {
    var self = this;
    node.addNode()
    
    var $parent = $('.dd').find('*').filter(function() {
		return $(this).text() === node.id;
    }).parent().parent();

    if ($parent.prop('tagName') == 'LI') {
      if (!$parent
        .hasClass('mjs-nestedSortable-expanded')) {
        $parent
          .addClass('mjs-nestedSortable-expanded');
      }
      if ($parent
        .hasClass('mjs-nestedSortable-collapsed')) {
        $parent
          .removeClass('mjs-nestedSortable-collapsed');
      }

    }
  }
};
ko.applyBindings(new viewModel());

$('.sortable')
  .nestedSortable({
    startCollapsed: true
  });
代码语言:javascript
复制
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;
}
.sortable .disclose {
  cursor: pointer;
  width: 10px;
  display: none;
}
.sortable li.mjs-nestedSortable-collapsed>ol {
  display: none;
}
.sortable li.mjs-nestedSortable-branch>div>.disclose {
  display: inline-block;
}
.sortable li.mjs-nestedSortable-collapsed>div>.disclose>span:before {
  content: '+ ';
}
.sortable li.mjs-nestedSortable-expanded>div>.disclose>span:before {
  content: '- ';
}
代码语言:javascript
复制
<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>
    <span class="disclose"><span></span></span>
    <span data-bind="text: id"></span>
    <a href="" data-bind="click: $root.addChild">Add child</a>
  </div>
  <ol class="sortable ui-sortable" data-bind="foreach: { data: children, as: 'child' }">
    <!-- ko if: child.children().length > 0 -->
    <li class="mjs-nestedSortable-collapsed 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>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34424283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档