9

你会怎么做这个?

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

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

4

5 回答 5

6

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


简短的回答是:如果您希望它具有反应性,这并不容易。要制作非响应式版本,只需将模板包装在标签中,然后按照@bento 的建议{{#constant}}连接 jquery-ui 可排序。render

要制作响应式版本,您的可排序小部件将不得不处理其下发生的变化(考虑在数据重新排序时处于中间拖动状态)。以下是一些关于你将如何去做的想法:

  1. 不幸的是,让它动画化并不容易,这将导致糟糕的用户体验。让我们暂时把它放在一边。

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

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

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

    一世。使用类似 jquery-ui 可拖动的东西,并将其连接renderitem模板上。您可能会遇到问题,因为如果从上游更改顺序,则底层元素可能会在拖动过程中消失。

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

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

我认为非常需要这样一个小部件,以一种快速的方式完成。它在我个人的雷达上(但很多事情也是如此,包括用动画重新排序的好方法)。

于 2012-11-05T07:02:34.817 回答
5

Meteor 的新渲染引擎 Blaze 现在可以更好地使用 jQuery。这是一个简短的视频,展示了如何使用 Meteor 和 jQuery-UI-sortable 实现可排序列表。

代码可以在 GitHub 上的 Meteor 存储库中的示例文件夹中找到。

于 2014-05-09T14:43:20.427 回答
2

2014 年 10 月,Differential 发布了带有 Meteor 和 jQuery UI 的可排序列表的最新示例:

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

请注意,在 Meteor 切换到 Blaze 模板引擎后,以前的解决方案可能无法正常工作。

于 2014-11-17T06:46:39.317 回答
2

**更新为 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();

}
于 2014-05-09T23:33:58.513 回答
0

我设法分别使用jQuery UI sortableMeteor Collection HookscontentEditable实现了一个拖放、可排序和可编辑的列表。有关部分工作的示例,请查看此演示

我的实现如下(不幸的是,它不是一个简单的即插即用示例,但我希望尽快为这个特定示例启动并运行一个演示):

用于拖放和保存的客户端 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 Behaviors和/或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

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

PS:如果您不了解 CoffeeScript,请将代码复制到这个令人难以置信的工具(Js2coffee)中。

编辑:请在此处查看独立版本:演示(在 Meteor 的服务器上非常慢)和源代码

于 2014-04-25T10:14:23.397 回答