将编号应用于Jquery可排序列表的最佳方法是什么?

时间:2015-03-10 22:40:41

标签: javascript jquery meteor

在尝试了一些方法后,我搜索了高低,以便找到一个看似简单的问题的好方法。

我有一个可排序的章节列表,我正在使用平均来为流星应用程序进行jquery可排序的工作。拖放可排序部分很容易(使用平均值),但应用章节的正确(整数)顺序非常棘手。

常见的应用程序是应用于目录的章节编号。

我尝试了什么:

  1. 使用for循环来重写stop:function,以解决不同的场景。拖到前面,拖到后面
  2. 随着章节数量的增加,这会变得复杂。我觉得解决方案太复杂了。

    1. 使用jQuery识别项目的顺序,并根据浏览器中的排序顺序应用数字。我认为这样可行,但我无法弄清楚使用什么jquery函数以及在尝试了几个之后的位置。免责声明:我是Spacebars的新手,并没有太多使用jquery。
    2. chaptersList html:

      <template name="chaptersList">
        <div id="items">              
         {{#each publishedChapters}}
            {{> chapterItem}}
         {{/each}}
       </div><!--items-->
      </template>
      

      chaptersList js:

          Template.chaptersList.rendered = function() {
            this.$('#items').sortable({
              stop: function(e, ui) {
                // get the dragged html element and the one before
                //   and after it
                el = ui.item.get(0)
                before = ui.item.prev().get(0)
                after = ui.item.next().get(0)
      
                if(!before) {
                  //if it was dragged into the first position grab the
                  // next element's data context and subtract one from the order
                  newOrder = 1;
                } else if(!after) {
                  //if it was dragged into the last position grab the
                  //  previous element's data context and add one to the order
                  newOrder = Blaze.getData(before).order + 1
                }
                else
                  //else take the average of the two orders of the previous
                  // and next elements
                  newOrder = (Blaze.getData(after).order +
                             Blaze.getData(before).order)/2
      
                  newOrder = Math.round(newOrder)
      
                //update the Items' orders
                Chapters.update({_id: Blaze.getData(el)._id}, {$set: {order: newOrder}})
              }
            })
          }
      
          Template.chaptersList.helpers({
      
            publishedChapters: function() { 
                                 return Chapters.find({ published: true }, 
                                 { sort: {order: 1} 
                               }); 
            },
      
            items: function() { 
                   return Chapters.find({}, { 
                         sort: {order: 1 } 
                   }) 
             }
          });
      

      chapterItem html:

          <template name="chapterItem">
      
                  <div class="item">
      
                      <h3 class="headroom-10 chapter-title-small">
                        <a href="{{pathFor 'showChapter'}}">{{title}}</a>
                      </h3>
                      <p class="chapter-text">{{#markdown}}{{chapterTease}}{{/markdown}}</p>
      
                      {{#if ownChapter}}
                        <a href="{{pathFor 'editChapter'}}" class="chapter-text">Edit</a>
                        <span class="delete">
                            <a href="#">Delete</a>
                        </span>
                      {{/if}}
                  </div>
      
          </template>
      

      感谢您的宝贵见解。

2 个答案:

答案 0 :(得分:1)

我经历了同样的问题,并且在我的案例中让它干净利落的技巧是从排序中取消可排序的操作,让Blaze在项目被删除后接管。否则,可排序的排序和Blaze排序最终会互相摔跤。

我将新订购的商品保存为一个批次,但这不一定是必需的。

Template.builder.rendered = function(){
  var self = this;
  this.$("ol.sortable").sortable({
    axis: "y",
    containment: "ol.sortable",
    tolerance: "pointer",
    update: function(event, ui){
      var
        items = $(this).find("li"),
        picks = _.map(items, function(item){
          var obj = Blaze.getData(item);
          obj.position = $(item).index() + 1;
          return obj;
        });

      self.$('ol.sortable').sortable('cancel');

      Meteor.call(
        "orderPicks",
        team,
        picks,
        function(error, result){}
      );
    }
  });
}

在服务器上:

Meteor.methods({
  orderPicks: function(team, picks){
    Teams.update(team,
      { $set: {picks: picks} }
    );
    return true;
  }
});

我相信我从另一个SO线程中选择了这个;我不记得了。无论如何,它可以无缝地适用于一组中等大小的物品。

HTML:

<template name="builder">
  <ol class="builder sortable">
    {{#each team.picks}}
      <li>{{position}}. {{name}}</li>
    {{/each}}
  </ol>
</template>

答案 1 :(得分:0)

这个答案是对@jeremy上述对话的跟进,使嵌套数组方法适用于单个文档。

它目前无法正常运行,但通过在此处发布,我希望能够获得洞察力,让它发挥作用并提供另一种解决方案。

现在,拖放项目时排序顺序不会改变。如果您能看到原因,请告诉我,或者您也可以编辑答案:

将ID添加到li:

chapterId: function() {
  return Chapters.findOne(this._id)._id
}

HTML:

<li class="item headroom-20" id="{{chapterId}}">

可排序的JS:

Template.chaptersList.rendered = function(){
  var self = this;
  this.$("ol.items").sortable({
    axis: "y",
    containment: "ol.items",
    tolerance: "pointer",
    update: function(event, ui){
      var items = $(".items").find("li");
      var publishedChaptersCount = items.length;
      var sortedIds = [];
      for (var i = 0; i < publishedChaptersCount; i++) {
        var obj = $(items[i]).attr('id');
        sortedIds.push(obj);
      }

      self.$('ol.items').sortable('cancel');

      Meteor.call(
        "chapterOrderUpdate",
        sortedIds,
        function(error, result){}
      );
    }
  });
}

流星法:

Meteor.methods({

  chapterOrderUpdate: function(sortedIds){
    var publishedChaptersCount = sortedIds.length;
    for (var i = 0; i < publishedChaptersCount; i++) {
      var chapterId = sortedIds[i];
      Chapters.update({_id: chapterId}, { $set: { order: i+1 } })
    }
  }
});