淘汰赛 & JQueryUI Drag - 是什么导致该元素不可拖动?

发布于 2024-12-24 21:43:41 字数 611 浏览 0 评论 0 原文

我正在尝试在使用 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>

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

任何人都可以找出可能导致此功能无法正常运行的原因吗?

I'm trying to make a list item draggable in a project that is using Knockout.js.

I'm using the code below, and as you can see it is very simple:

<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>

The list of 'room' renders just fine, but none of the items are draggable. However, if I apply the 'draggable' class to any other element on the page - it becomes draggable. Even if they are other list items. The only difference is that these list items are being created through the 'foreach' binding.

Can anyone spot what may be causing this to not function correctly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

救赎№ 2024-12-31 21:43:41

foreach 的工作原理是保存元素的副本,以便在需要渲染项目时用作“模板”。因此,您设置为可拖动的元素不是由 foreach 渲染的元素。

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

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

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

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

或者你可以做一些更好的事情,你实际上根据你的项目被删除的位置更新一个 observableArray 。

我不久前在此处写了一篇文章。在 Knockout 2.0 中,我做了一些更改来简化绑定,以便您可以在父级上使用 sortableList

这是一个仅可排序的示例: http://jsfiddle.net/rniemeyer/DVRVQ/

这是一个在之间删除的示例列表:http://jsfiddle.net/rniemeyer/sBHaP/

foreach works by saving off a copy of the elements to use as the "template" whenever it needs to render an item. So, the elements that you made draggable are not the ones that were rendered by foreach.

You could try to make sure that draggable is called after applyBindings, but that would only be effective if your rooms is not an observableArray that changes. Any new items rendered would not be draggable.

Another option is to use the afterRender option to call draggable on your elements.

A better way is to use a custom binding. It could be as simple as:

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

or you can get into something a little better where you actually update an observableArray based on where your items are dropped.

I wrote an article a while back on it here. With Knockout 2.0, I made a few changes to simplify the binding so that you can just use sortableList on the parent.

Here is a sample with just sortable: http://jsfiddle.net/rniemeyer/DVRVQ/

Here is a sample with dropping between lists: http://jsfiddle.net/rniemeyer/sBHaP/

一袭白衣梦中忆 2024-12-31 21:43:41

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

您需要的是在每次渲染 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>

The problem is that draggable() is applied when document is ready on existing elements. Knockout.js will modify the HTML and create new elements at the beginning and also when the rooms array is updated.

What you need is to enable dragging each time the room-view is rendered. You can use afterRender for that.

Try this:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文