2016-08-13 21 views
2

したがって、基本的には、ng-repeatを使用してビューにデータをロードしています。ドラッグアンドドロップが発生すると、ディレクティブを使用して項目をあるグループから別のグループに移動します。ディレクティブは、サービス内のmove関数を呼び出し、リスト変数を更新します。サービス変数が角型で更新されるとウォッチは発生しません

私の問題は、アイテムを移動すると、ng-repeatが更新されないということです。私は$scope.$watchを使ってみましたが、運がありませんでした。サービスリスト変数が更新されていますが、何らかの理由で時計がトリガされていません。私はbroadcastを使ってみましたが、これはうまくいきましたが、コントローラでブロードキャストを使うのは悪い習慣だと読んだことがあります。

ng-repeatを更新する最も良い方法は何ですか?それがなぜ機能していないのか分かりません。詳細が必要な場合は、私にお知らせください。

これは、これは私のコントローラ

function MyController($scope, DataService) { 
    var vm = this; 

    vm.list = DataService.get(); 

    $scope.$watch(function() { 
     return DataService.get(); 
    }, function(value) { 
     console.log('Wtatching'); 
     console.log(value); 
    }, true); 
} 

マイビュー

<div ng-repeat="item in vm.list track by $index"> 
    <div class="group" droppable group="<% $index %>"> 
     <div class="group-title"> 
      <% group.title %> 
     </div> 
     <div class="group-content"> 
      <div ng-repeat="item in item.items track by $index"> 
       <div class="group-item"> 
        <div class="group-item-title" 
         draggable 
         group="<% $parent.$index %>" 
         item="<% $index %>"> 
         <% item.title %> 
        </div> 
       </div> 
      </div> 
     </div> 
    </div> 
</div> 

EDIT

である私のサービス

angular.module('Data', []) 
    .factory('DataService', DataService); 

function DataService() { 
    var list = []; 
    list.push({ 
     id: 6, 
     title: "First Group", 
     items: [ 
      { 
       id: 1, 
       title: "This is an item" 
      } 
     ] 
    }); 
    list.push({ 
     id: 7, 
     title: "Testng", 
     items: [ 
     ] 
    }); 

    return { 
     'get': get, 
     'move': move, 
    }; 

    function get() { 
     return list; 
    } 

    function move(index, fromItemIndex, toItemIndex) {  
     list[fromItemIndex].items.push({ 
       id: 5, 
       title: "This is an item" 
      }); 
    } 
} 

ですここにplnkerバージョンがあります:https://plnkr.co/edit/bQuotNU7oOm92PCgmhcj

アイテム1をドラッグしてそれ自身にドロップすると、サービスリストは更新されていますが、ウォッチはトリガーされません。

+2

plunke r/fiddleは素晴らしい追加です。 –

+0

<% %>とはどのような構文ですか? {{}} –

+1

@Beardslapperが補間記号を変更したようです。https://docs.angularjs.org/api/ng/provider/$interpolateProvider –

答えて

2

私はこの問題があなたのng-repeatという表現であると思います。 track by $indexを削除してみてください。

function move(index, fromItemIndex, toItemIndex) { 
    $timeout(function() { 
     list[fromItemIndex].items.push({ 
      id: 5, 
      title: "This is an item" 
     }); 
    }); 
} 

を使用すると、注入を確認してください:

あなたが項目(ドラッグ&ドロップ)を移動するためのjQueryの(または他の非角度コールバック)を使用している場合は、あなたは、このようなあなたのmoveコードをラップする必要があります工場出荷時は$timeoutです。 digest cycleという概念がAngularにあり、AngularはAngularコンテキスト内でデータを定期的に更新します。ドキュメントから

$ダイジェスト段階ではスコープは、$ウォッチ式のすべてを調べ 、前の値と比較します。この汚れたチェックは非同期で で行われます。

いくつかの角度データは、jQueryのドラッグ&ドロップ&のような非角度コンテキストに変更した場合、あなたがそれを言うまで、角度はその変化に気付かないだろう。したがって、$scope.$apply()を使用すると、何かが変更されたことをAngularに伝えることができます。しかし、$apply()は、ダイジェストサイクルが既に進行中である場合に、時には失敗します。そのため、角型のラップされたサービス($timeoutなど)を使用することをお勧めします。

要旨:

$timeoutが暗黙のうちにここダイジェストサイクルに

もっと詳細をトリガするために使用されます。https://docs.angularjs.org/error/ $ rootScope/INPROG#トリガ・イベント・プログラムで

(考えてみましょうjQueryベースのライブラリを使用している場合はAngular UIチームによって管理されているUI.Sortableを使用してください)

+0

$タイムアウトを追加すると問題が解決したようです。なぜタイムアウトなしで動作しないのでしょうか?また、$タイムアウトを追加することで、$ watchをセットアップする必要はありませんでした。 – Beardslapper

+1

更新された理由を確認してください。 –

+1

パーフェクト。この有益な投稿を書くためにあなたの助けと投資してくれてありがとう。それは本当に私を助けてくれました。 – Beardslapper

関連する問題