2013-07-26 20 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

在你的鏈接功能,你可以嘗試使用$ timout(函數(){//接入電網兒童},0); – Chandermani

+0

確實有效,但這種方法可靠嗎? –

+0

其實你的子模板在post鏈接函數後得到渲染,所以你需要添加$ timout,它會起作用,因爲它會引入一些延遲。 – Chandermani

回答

0

要實現重新排序,你有幾種選擇:

  1. 操作DOM。恕我直言,這是最不喜歡的方式,它不是非常有角度的。
  2. 在鏈接功能中重新排列在ngRepeat中使用的數組([1,2,3])。
  3. 使用orderBy過濾器(doc

我創建了一個普拉克證明2和3,希望它可以幫助。 http://plnkr.co/edit/vrgeBoJZiG6WMu4Rk46u?p=preview

+0

我可能會誤導你使用「重新排序」術語。我的目標更多是將元素重新排列爲網格(例如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 - 如果設置爲false跳過模式髒檢查,否則會則啓動內部的$ FN適用塊。 (默認:真

調用$timeout將強制$digest週期 - 所以你的時間記錄孩子 - 的ng-repeat指令將「完成」。與ng-repeat的比賽是這個問題的癥結所在 - 因爲在我們進入我們的link函數時,它仍然在做這件事。


就可以解決這個問題的另一種方式 - 這當然是不常見的 - 但在說明事件的更詳細的序列做了偉大的工作,是如下...

.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 - 簡單的演示展示了這兩種方法

相關問題