3

複数の並べ替え可能なリストを管理するために、AngularUI 内で Sortable を使用しています。リスト間でアイテムを簡単に移動し、それに応じて対応するモデルを更新できるようになりました。ただし、クエリ フィルターを含めると、次の場合に少し問題が発生します。

  1. ユーザーが、リストの最初のエントリではないアイテムの検索フィールドを入力しました。
  2. ユーザーは、フィルター処理された結果の最初の項目をあるリストから別のリストに移動します。
  3. クエリがクリアされ、最初のリストが表示されるまで、機能しているようです。クエリを適用したときにエントリを移動したように見えますが、クリアした後、フィルター処理されていない配列の最初のエントリが代わりに移動されたことに気付くでしょう。

ドラッグ アンド ドロップするとき、Sortable はフィルターを考慮していないようです。関連する HTML は次のとおりです。

  <p>Search: <input ng-model="query" /></p>
  <div class="column-wrapper">
    <ul ui-sortable="sortableTemplates" ng-model="list1" id="sortable1" class="connectedSortable">
      <li ng-repeat="item in list1|filter:query" class="itemBox">{{item.name}}</li>
    </ul>
    <ul ui-sortable="sortableTemplates" ng-model="list2" id="sortable2" class="connectedSortable">
      <li ng-repeat="item in list2|filter:query" class="itemBox">{{item.name}}</li>
    </ul>
  </div>

そして対応する JS:

var app = angular.module('myApp', ['ui.sortable']);
app.controller('test', function($scope) {

$scope.list1 = [
    {name: 'ABC'},
    {name: 'DEF'},
    {name: 'GHI'}
];

$scope.list2 = [
    {name: 'JKL'},
    {name: 'MNO'},
    {name: 'QRS'}
];

$scope.sortableTemplates = {
    connectWith: '.connectedSortable'
}

});

ここでは、Plunker で実行しています。

問題を再現するには、 を検索してから list2GHIに移動してみてください。GHI次に、検索ボックスをクリアします。ABC実際に list2 に移動するのは (その配列の最初の要素であるため)、GHIリスト 1 に残ります。

リスト間でソートするときに元のインデックスが保持されるように、ソート可能な Angular フィルターを使用する方法はありますか?

(私は Angular と JQueryUI を初めて使用するので、答えは明白かもしれません。同様の質問を見つけましたが、この問題に直接対処しているようには見えませんでした。)

4

1 に答える 1

3

あなたが言うように、ui-sortable は要素インデックスを使用してリスト間で移動するため、フィルター処理されたリストの最初のアイテムを移動すると、元のリストの最初のアイテムが移動します。これを回避する1つの方法は、リストをフィルタリングする代わりに、ng-repeatのフィルターのように新しいリストを作成するのではなく、移動したくないアイテムを非表示にすることです. あなたのhtmlで:

<li ng-repeat="item in list1" class="itemBox" ng-show="visible(item)">{{item.name}}</li>

$scope.visible(item) が true または false を返すかどうかに応じて、ng-show は要素を表示または非表示にします。したがって、要素を表示したい場合、つまりフィルターで除外されていない場合は true を返し、フィルターで除外されている場合は false を返す関数をコントローラーに作成します。

$scope.visible=function(item){
  //create an array containing all of the elements in both lists
  var lists=$scope.list1.concat($scope.list2);
  // filter this list using our search term
  var filteredItems=$filter('filter')(lists, $scope.query);
  //if there are no matching items left in our list then return false
  if (filteredItems.length===0){return false;}
  //see if the current item is in the filtered list   
  if (($filter('filter')(filteredItems,item)).length===1){
     return true;
  } else {
     return false;
  }
}

http://plnkr.co/edit/JCQdcP?p=previewでプランカーを作成しました

于 2013-09-29T08:59:14.917 に答える