0

我正在快速更新排序的 Knockout 数组的内容,发现我实际上无法与快速更新的项目进行交互。这是一个大大简化的示例:

<script type="text/html" id="link-template">
    <a data-bind="text: name" href="https://stackoverflow.com"></a>
</script>

<ul data-bind="template: { name: 'link-template', foreach: links }"></ul>

<script>
    var Link = function(name) {
        this.name = ko.observable(name);
    };

    var Vm = function() {
        this.links = ko.observableArray();
    };

    var model = new Vm();
    model.links.push(new Link('link1'));
    model.links.push(new Link('link2'));
    ko.applyBindings(model);

    setInterval(function() {
        var len = model.links().length;
        var target = Math.floor(Math.random() * len);
        var removed = model.links.splice(target, 1);
        model.links.unshift(removed[0]);
    }, 1000 / 30);
</script>

我的意图是首先订购最近更新的链接,在这里用随机更新进行模拟。直接更新,model.links()[0].name('...')允许我点击项目上的链接,但我也想支持重新排序。

尝试与快速更新的数组交互是一种非常糟糕的用户体验,所以我认为最好的解决方案是推迟对列表中的元素重新排序,直到用户不再将鼠标悬停在它上面,从而将显示的数组与数据数组解耦。其他列表元素仍应围绕固定的活动元素重新排序。

在 Knockout 中有什么简单的方法可以做到这一点吗?是否有任何现有的插件可以做到这一点?

4

1 回答 1

0

根据链接的 observableArray 创建一个计算值。当鼠标在 中时ul,计算返回悬停开始时制作的副本;当鼠标不在时ul,计算返回当前链接列表。

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

    var allowReorder = ko.observable(true);

    var model = {
      links: ko.observableArray([
        new Link('link1'),
        new Link('link2')
      ]),
      allowReorder: ko.observable(true)
    };

    var copyOfLinks;
    model.allowReorder.subscribe(function(newValue) {
      if (!newValue) {
        copyOfLinks = model.links.slice(0);
      }
    });

    model.computedLinks = ko.computed(function() {
      if (model.allowReorder()) {
        return model.links()
      } else {
        return copyOfLinks;
      }
    });

    ko.applyBindings(model);

    setInterval(function() {
      var len = model.links().length;
      var target = Math.floor(Math.random() * len);
      var removed = model.links.splice(target, 1);
      model.links.unshift(removed[0]);
    }, 50);
<div>Something</div>
<ul data-bind="foreach: computedLinks, event: {mouseover:allowReorder.bind(null, false), mouseout:allowReorder.bind(null, true)}">
  <li>
    <a data-bind="text: name" href="https://stackoverflow.com"></a>
  </li>
</ul>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>

于 2015-07-13T15:05:03.067 回答