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. 残念ながら、アニメーション化するのは簡単ではなく、UX の低下につながります。それは今は置いておきましょう。

  2. 次のようなアイテムをレンダリングします。 {{#each items}} {{> item}} {{/item}}

    これは、サーバーからデータが送信されたときに自動的に並べ替えられます (アニメーションなし)。

  3. レンダリング時に各アイテムをドラッグ可能に設定します。あなたはどちらかできます

    私。jquery-ui draggable などを使用しrenderて、itemテンプレートに接続します。順序が上流から変更されると、ドラッグ中に下にある要素が消える可能性があるため、これを行うと問題が発生する可能性があります。

    ii. おそらく下位レベルのライブラリを使用して、独自のドラッグ コードを実装します。

  4. アイテムが所定の位置にドラッグされたら、すぐにリストをローカルで並べ替えます (そうすれば、ユーザーは正しいものを見るはずです。サーバーが変更を尊重することを願っています..しかし、それにも立ち入らないでください)。

流星のような方法で行われるこのようなウィジェットには大きなニーズがあると思います。それは私の個人的なレーダーにあります(しかし、アニメーションで再注文する良い方法を含む多くのこともそうです).

于 2012-11-05T07:02:34.817 に答える
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 sortableとMeteor 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 BehaviorsMongo 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 を理解していない場合は、この素晴らしいツール (Js2coffee)にコードをコピーしてください。

編集: ここでスタンドアロン バージョンを参照してください:デモ(Meteor のサーバーでは非常に遅い) とソース コード

于 2014-04-25T10:14:23.397 に答える