淘汰赛JQueryUI Drag - 导致此元素无法拖动的原因是什么?

时间:2012-01-06 01:19:08

标签: jquery jquery-ui knockout.js

我正在尝试在使用Knockout.js的项目中创建一个可拖动的列表项。

我正在使用下面的代码,正如您所看到的那样非常简单:

<div id="room-view" >
    <ul data-bind="foreach: rooms">                     
        <li data-bind="text: name" class="draggable room-shape"></li>                   
    </ul>               
</div> 

<script type="text/javascript">
    $(function() {
        $( ".draggable" ).draggable();
    });
</script>

'room'列表渲染得很好,但没有一个项目是可拖动的。但是,如果我将'draggable'类应用于页面上的任何其他元素 - 它将变为可拖动。即使它们是其他列表项。唯一的区别是这些列表项是通过'foreach'绑定创建的。

有人能发现可能导致其无法正常运作的原因吗?

2 个答案:

答案 0 :(得分:23)

foreach的工作原理是,只要需要渲染项目,就可以保存要用作“模板”的元素副本。因此,您可拖动的元素不是由foreach呈现的元素。

您可以尝试确保在draggable之后调用applyBindings,但这只有在您的rooms不是更改的observableArray时才会生效。呈现的任何新项目都不可拖动。

另一种选择是使用afterRender选项在元素上调用draggable

更好的方法是使用自定义绑定。它可以很简单:

ko.bindingHandlers.draggable = {
   init: function(element) {
       $(element).draggable();
   }
};

或者你可以根据你的项目被丢弃的位置实际更新observableArray,以获得更好的效果。

我一段时间写了一篇文章here。使用Knockout 2.0,我进行了一些更改以简化绑定,以便您可以在父级上使用sortableList

以下是可排序的示例:http://jsfiddle.net/rniemeyer/DVRVQ/

以下是列表之间删除的示例:http://jsfiddle.net/rniemeyer/sBHaP/

答案 1 :(得分:7)

问题是,当现有元素上的文档准备就绪时,会应用draggable()。 Knockout.js将修改HTML并在开始时以及更新rooms数组时创建新元素。

您需要的是每次呈现room-view时启用拖动。您可以使用afterRender

试试这个:

<div id="room-view" >
  <ul data-bind="foreach: { data: rooms, afterRender: afterRender }">                     
    <li data-bind="text: name" class="draggable room-shape"></li>                   
  </ul>               
</div> 

<script type="text/javascript">
  // this is your already existing view-model that contains rooms, etc
  function roomsViewModel() {
    // ...

    // insert this in your view-model
    this.afterRender = function() {
      $( ".draggable" ).draggable();
    }
  }

  ko.applyBindings(new roomsViewModel());
</script>