在Meteor中拖放可排序列表

时间:2012-11-03 23:54:10

标签: meteor jquery-ui-sortable collaboration

你会怎么做?

列表中的项目可以对应于集合中的记录,并且它们在列表中的位置可以对应于每个记录上的字段(可能是“等级”),当“停止”事件发生时,该字段必须被更新。

Meteor能否与jQueryUI Sortable很好地配合?如果多个用户尝试一次拖动和排序相同的列表会发生什么? Meteor是否需要定制的排序行为?

5 个答案:

答案 0 :(得分:6)

编辑:以下答案已过时,@ cutemachine的答案或http://blog.differential.com/sortable-lists-in-meteor-using-jquery-ui更接近现有技术水平。


简短的回答是:如果你希望它被反应,这并不容易。要创建一个非反应性版本,只需将您的模板包装在{{#constant}}标记中,然后将@ render中的jquery-ui挂钩为@bento建议。

要制作一个被动版本,你的可排序小部件将不得不处理它下面发生变化的事情(想想当数据重新排序时,它是中等阻力)。以下是关于如何实现它的一些想法:

  1. 不幸的是,制作动画并不容易,这会导致用户体验不佳。我们暂时搁置一边。

  2. 使用以下内容渲染项目: {{#each items}} {{> item}} {{/item}}

    当数据从服务器下来时(无动画),这将重新排序。

  3. 将每个项目设置为在呈现时可拖动。你可以

    我。使用像jquery-ui draggable这样的东西,然后在render模板的item中将其连接起来。您可能在执行此操作时遇到问题,因为如果排序从上游更改,则基础元素可能会在拖动过程中消失。

    II。实现您自己的拖动代码,可能使用较低级别的库。

  4. 当一个项目被拖动到位时,立即在本地重新排序列表(这样用户应该看到正确的东西。希望服务器会尊重这个变化......但是我们也不会考虑到这一点。)

  5. 我认为这种小部件非常需要,以流畅的方式完成。这是我个人的关注(但很多事情都是如此,包括用动画重新订购的好方法)。

答案 1 :(得分:4)

Meteor的新渲染引擎Blaze现在可以更好地使用jQuery。 Here is short video展示了如何使用Meteor和jQuery-UI排序实现可排序列表。

code can be found in the Meteor repository on GitHub in the example folder

答案 2 :(得分:2)

最新的Meteor和jQuery UI可排序列表示例于2014年10月由Differential发布:

http://differential.com/blog/sortable-lists-in-meteor-using-jquery-ui

请注意,在Meteor切换到Blaze模板引擎后,之前的解决方案可能无效。

答案 3 :(得分:1)

**已更新为1.0

查看MeteorPad:http://meteorpad.com/pad/TzQTngcy7PivnCCjk/sortable%20demo

这是我实施的版本 - 与@ tomsabin非常相似,但不需要收集行为。它对我有多个用户的效果很好,并且是被动的。

<强> HTML (将div ID与_id相同可能不是一个好主意,我相信你会找到更好的解决方法。)

<template name="myList">
  <div class="step_list">
    {{#each card}}
      {{> card_template}}          
    {{/each}}
  </div>
</template>

<template name="card_template">
  <div class="card" id="{{_id}}">             
       <h3>{{name}}</h3>   
  </div>
</template>

<强> JS

Template.myList.helpers ({
    card : function () {
        return Cards.find({}, {sort: {pos: 1}}
    )}
})

Template.myList.rendered = function(){

     $(".step_list").sortable({
       items: ".card",
       delay: 100,
       refreshPositions: true,
       revert: true,
       helper: "clone",
       scroll: true,
       scrollSensitivity: 50,
       scrollSpeed: 35,
       start: function(event, ui) {
        $(ui.helper).addClass("dragging");
       }, // end of start
       stop: function(event, ui) {
        $(ui.item).removeClass("dragging");
       }, // end of stop
       update: function(event, ui) {
        var index = 0;                   
        _.each($(".card"), function(item) {
          Cards.update({_id: item.id}, {
            $set:{
              pos: index++,
            }
          });
        });
      } 
    }).disableSelection();

}

答案 4 :(得分:0)

我设法分别使用jQuery UI sortableMeteor Collection Hooks以及contentEditable来实施拖放,可排序和可编辑的列表。有关部分工作示例,请查看this demo

我的实现如下(不幸的是它不会是一个简单的插件和示例,但我希望很快得到一个演示并运行这个特定的例子):

用于拖放和保存的客户端JS:

Template.templateName.rendered = ->
  Deps.autorun ->
    $('#list').sortable
      handle: '.handle'
      stop: (event, ui) ->
        _.each $(event.target).children('div'), (element, index, list) ->
          Elements.update { _id: element.getAttribute('data-element-id') },
            $set: position: index + 1

这里很少有人注意到,我使用'手柄'来拖动元素,因为每个div内部都有其他按钮和可编辑内容。用户拖动元素并将其放置到位后,“停止”事件开始,我使用新定位更新该列表中的每个元素。

我还可以向页面添加元素,这些元素将位于列表的底部。否则,您可能会使用Meteor Collection Behaviours和/或Mongo Counter软件包。但是,我使用Meteor Collection Hooks#.before.insert如下:

挂钩前的集合

@Elements.before.insert (userId, doc) ->
  highestElement = Elements.findOne({},
                     sort: { position: -1 }
                     limit: 1
                   )
  position = if highestElement? then highestElement.position else 0
  doc.position = position + 1

这里我们只是获取最高文档,对position属性进行排序。如果它不存在(例如,要创建的第一个元素),那么我们将位置初始化为1。

PS:如果您不理解CoffeeScript,请将此代码复制到此incredible tool (Js2coffee)

编辑:请在此处查看独立版本:demo(在Meteor的服务器上非常慢)和source code