2013-07-26 5 views
6

グリッドとしてコンテンツを並べ替えるカスタムディレクティブを作成しようとしています。 ng-repeat指示の結果をクロールし、結果の要素を並べ替える必要があります。カスタムディレクティブのng-repeat子要素のハンドルを取得するにはどうすればよいですか?

リンク機能内でelement.children()メソッドを呼び出すと、ng-repeatディレクティブがまだレンダリングされていないためコメントとして解釈されるため、空の配列があります。

それ以外の場合、ディレクティブは内容が「静的」であれば効果的です。

HTML

<grid n='6'> 
    <div ng-repeat="i in [1,2,3]"></div> 
</grid> 

コードの唯一の興味深い作品と私​​のディレクティブ:

app.directive('grid', [function() { 
    return { 

     restrict: 'E', 
     replace: true, 
     transclude: true, 
     template: "<div ng-transclude></div>", 

     link: function (scope, grid, attrs) { 

      // With an ngRepeat transcluded, els result in an empty array 
      var els = grid.children(); 

      // ... 
    }; 
}]); 

私は何をしないのですか?並べ替えを達成するために

+2

に近づく両方。 – Chandermani

+0

確かに動作しますが、この方法は信頼できますか? –

+0

実際にあなたの子テンプレートはポストリンク関数の後にレンダリングされるので、$ timoutを追加する必要があります。 – Chandermani

答えて

0

、あなたはいくつかのオプションがあります。

  1. は、DOMを操作します。 IMHO、これは最も好まれない方法です、それほど角度がありません。
  2. リンク機能でngRepeatで使用されている配列([1,2,3])を並べ替えます。
  3. orderByフィルタ(doc

使用私は2と3を実証するplunkを作成しました、それが役立つことを願って。 http://plnkr.co/edit/vrgeBoJZiG6WMu4Rk46u?p=preview

+0

私は 'reorder'の言葉であなたを誤解しているかもしれません。私の目標は、要素をグリッド(例えば3要素/行)として並べ替えることでした。とにかくありがとうございました ;) –

0

これにはいくつかの方法があります。コメントは提案として、あなたが表示されます最も簡単で一般的な解決策はある - などのレバレッジ$timeout ...

.directive('grid', ['$timeout', function ($timeout) { 
    return { 
     restrict: 'E', 
     replace: true, 
     transclude: true, 
     template: '<div ng-transclude></div>', 
     link: function (scope, grid, attrs) { 
      $timeout(function() { 
       console.log(grid.children()); 
      }); 
     } 
    } 
}]); 

$タイムアウト([FN]、[遅延]、[invokeApply]、[パス]);

[...]

invokeApply - 偽スキップモデルダーティチェックに設定されている場合は、それ以外のブロックを適用$以内にFNを呼び出します。 (デフォルト:真

$digestサイクルを強制します$timeoutを呼び出す - その時点であなたは子供ログ - ng-repeat指示がされる「完了。」 ng-repeatのレースは、ここでの問題の要点です.の機能を入力するまでにはまだそれが行われているからです。我々はここではなく、イベントのより詳細な手順を示すで素晴らしい仕事をして、次のようである...

.directive('grid', [function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     transclude: true, 
     template: '<div ng-transclude></div>', 
     link: function (scope, grid, attrs) { 
      scope.$on('repeat-done', function() { 
       console.log(grid.children()); 
      }); 
     } 
    } 
}]) 
.directive('ngRepeat', [function() { 
    return { 
     restrict: 'A', 
     link: function (scope, elem, attrs) { 
      if (scope.$last) 
       scope.$root.$broadcast('repeat-done'); 
     } 
    }; 
}]); 

-


あなたがこの問題を解決することができます別の方法 - 確かに、あまり一般的です控えめに、完了時にng-repeatを呼び出して関数を呼び出すことができます。そして、我々はlink関数の中で$onによってこれを購読することができます。


JSFiddle Link - 簡単なデモ展示しますが$ TIMOUT(関数(){//アクセスグリッドの子供}、0)を使用して試すことができますあなたのリンク機能の中で

関連する問題