14

問題:

jQuery から Draggable + Sortable 機能を再作成しようとしていますが、ドロップされた要素をオブジェクトの配列に入れることができません。

$.draggable()ボタンを$.sortable()リストにドラッグしたい。ボタンがプロパティを持つオブジェクト (連想配列またはオブジェクト自体である可能性があります) を表すようにしたいのですが、リストにドロップすると、ドロップされた位置の配列にボタン自体を配置する必要があります。


明確にするために、左側のメニューに潜在的なオブジェクトの配列があります。右側では$http、API を呼び出して、すべてのフィールドが に保持されているフォームを取得しています$scope。その潜在的なオブジェクト (のようなtextarea) を、そのフォームのフィールドのドロップされた位置にドロップしたいと考えています。

jquery ビットは簡単ですが、$scope配列内の位置にオブジェクトが存在しないことが問題です。


私が試したこと:

コーミングui-sortable$.draggableディレクティブ ラッパーの混合に近づいていましたが、コードがうまく機能しません。


例:


更新 1:

ui-sortablelike ディレクティブをラップするディレクティブと組み合わせて進歩しましたが$.draggable()、ちょっと醜いですが機能します。

更新 2:

現在は動作していますが、jquery からインデックスを取得し、PHP を使用してその位置にスライスし、リスト全体をリロードします。不自由について話してください。もっと良い方法があるはずです。

更新 3:

これは、誰のアプリでもモジュール化された実際の例です。

4

2 に答える 2

18

新しい要素または移動した要素の位置を見つけるのに役立つ角度マジックはありませんが、jQuery を使用すると簡単に行うことができます。ディレクティブでソート可能およびドラッグ可能をラップする jQueryUI-demo の例を作成しました。

http://plnkr.co/edit/aSOlqR0UwBOXgpQSFKOH?p=preview

<ul>
  <li my-draggable="#sortable" class="ui-state-highlight">Drag me down</li>
</ul>

<ul my-sortable id="sortable">
  <li class="ui-state-default" ng-repeat="item in items">{{item.name}}</li>
</ul>

my の値はmy-draggable、対応する要素の IDmy-sortableです。my-draggable は、それ以外の場合は非常に簡単です。

app.directive('myDraggable',function(){

  return {
    link:function(scope,el,attrs){
      el.draggable({
        connectToSortable: attrs.myDraggable,
        helper: "clone",
        revert: "invalid"
    });
    el.disableSelection();
    }
  }
})

要素がドロップされたことを示すイベントをmy-sortableリッスンします。ng-repeat のソースである配列内の要素の位置です。ng-repeat は、配列内の現在の要素の位置を示す $index 変数を使用して、各要素の子スコープを作成します。$index が定義されていない場合、それが新しい要素であることがわかります (これを判断するためのより良い方法かもしれませんが、この例では機能します)。アイテムの新しい位置です。既存の要素が移動された場合は 'my-sorted' イベントを $emit し、新しいアイテムが追加された場合は 'my-created' イベントを $emit します。deactivatefromto

app.directive('mySortable',function(){
  return {
    link:function(scope,el,attrs){
      el.sortable({
        revert: true
      });
      el.disableSelection();

      el.on( "sortdeactivate", function( event, ui ) { 
        var from = angular.element(ui.item).scope().$index;
        var to = el.children().index(ui.item);
        if(to>=0){
          scope.$apply(function(){
            if(from>=0){
              scope.$emit('my-sorted', {from:from,to:to});
            }else{
              scope.$emit('my-created', {to:to, name:ui.item.text()});
              ui.item.remove();
            }
          })
        }
      } );
    }
  }
})

コントローラーで items-array を作成し、イベントをリッスンします。

$scope.items = [
  {name:'Item 1'},
  {name:'Item 2'},
  {name:'Item 3'},
  {name:'Item 4'},
];

$scope.$on('my-sorted',function(ev,val){
  // rearrange $scope.items
  $scope.items.splice(val.to, 0, $scope.items.splice(val.from, 1)[0]);
})

$scope.$on('my-created',function(ev,val){
  // create new item at position 
  $scope.items.splice(val.to, 0,
    {name:'#'+($scope.items.length+1)+': '+val.name});
})

ご覧のとおり、要素を追加または移動すると、スコープ内のモデルが更新されます。

これらのディレクティブはあまり一般的ではありません。アプリケーションで動作するようにするには、何らかの調整が必要になる場合があります。

于 2013-09-24T09:46:08.187 に答える
1

リンク機能で必要なことはすべて実行できるはずです。

myapp.directive("menuDrag", function () {

    return{
        restrict: "A",
        link:     function (scope, element, attrs) {
            var item = $(".draggable").draggable(
                {
                    snap:   true,
                    revert: false,
                    // scope:".dropable"
                    //scope: "tasks"
                }
            )
            var target = $(".dropable").droppable({

                greedy:     true,
                hoverClass: "warning",
                accept:     ".draggable"
            })


            item.on("drag", function (evt) {
                item.css = ('background-color', 'red');
                //evt.stopPropagation();
                //evt.preventDefault();
            })


            target.on("over", function (evt) {

                target.css('background-color', 'blue')

                return false;
            });
            target.on("out", function (evt) {
                dropBox.css('background_color', 'red');


                return false;
            });
            target.on("drop", function (evt) {
                alert("Droped");
                return false;
            });
            //dragEnterLeave(evt);
        }
    }
})
于 2013-09-19T00:59:21.993 に答える