2014-12-02 54 views
2

我想打印父指令的ng-repeat迭代器的索引。僞代碼:AngularJS父指令範圍從內部ng-transclude

的index.html

<div data-repeatable> 
    {{$index}} does not display 
</div> 

template.html

<div ng-repeat="i in getTimes(5) track by $index"> 
    {{$index}} displays correctly 
    <div ng-transclude></div> 
</div> 

app.js

// Other code omitted 
.directive('repeatable', function() { 
     return { 
     scope: {}, 
     transclude: true, 
     templateUrl: 'template.html' 
     }; 
    }) 

我過電子郵件的探索了許多不同的方法/調整,但迄今爲止沒有任何工作。任何幫助將不勝感激!

謝謝。

+0

將範圍從父項傳遞給子項並檢入指令控制器是否存在如果不更新'$ scope.index ='number''它會自動更新父項 – 2014-12-02 03:49:44

回答

0

好的,所以它可能非常黑客,並依賴於AngularJS的內部實現細節,可能會在任何版本中被拉取,但仍然...這是我發現得到這個工作的一種方式。

請注意,這似乎只適用於Angular 1.3分支。

var app = angular.module('plunker', []); 
 

 
app.directive('repeatable', function($timeout) { 
 
    return { 
 
    scope: {}, 
 
    transclude: true, 
 
    templateUrl: 'template.html', 
 
    link: function(scope, elem, attrs, nullCtrl, transclude) { 
 
     scope.getTimes = function(n) { 
 
     var arr = []; 
 
     for (var i = 1; i <= n; i++) arr.push(i); 
 
     return arr; 
 
     }; 
 

 
     // needs to be done in $applyAsync so the ng-repeat has 
 
     // time to render all the items 
 
     scope.$applyAsync(function() { 
 
     // using the transclude function just to get hold of the transclude scope 
 
     transclude(function(clone, scope) { 
 
      var ngRepeatScopes = findChildScopesMatching(scope.$parent, isNgRptScope); 
 
      angular.forEach(ngRepeatScopes, function(ngRepeatScope) { 
 
      var transcludedScope = findTranscludedScope(ngRepeatScope); 
 
      transcludedScope.$index = ngRepeatScope.$index; 
 
      }); 
 
     }); 
 
     }); 
 

 
     function findChildScopesMatching(parentScope, predicateFn) { 
 
     var scopes = [], 
 
      currentScope = parentScope.$$childHead; 
 

 
     while (currentScope) { 
 
      if (predicateFn(currentScope)) 
 
      scopes.push(currentScope); 
 
      currentScope = currentScope.$$nextSibling; 
 
     } 
 
     return scopes; 
 
     } 
 

 
     function isNgRptScope(scope) { 
 
     return angular.isDefined(scope.$first) 
 
      && angular.isDefined(scope.$last) 
 
      && angular.isDefined(scope.$index); 
 
     } 
 

 
     function findTranscludedScope(scope) { 
 
     var transcludedScopes = findChildScopesMatching(scope, isTranscludedScope); 
 
     return transcludedScopes[0] || null; 
 
     } 
 

 
     function isTranscludedScope(scope) { 
 
     return scope.$$transcluded; 
 
     } 
 
    } 
 
    }; 
 
});
.ng-repeat-scope { 
 
    background-color: AliceBlue; 
 
    color: darkblue; 
 
    padding: 5px; 
 
    margin: 5px 0; 
 
} 
 
.ng-transcluded-scope { 
 
    background-color: LightGoldenRodYellow; 
 
    color: GoldenRod; 
 
    padding: 5px; 
 
    margin: 0 20px; 
 
} 
 
.nicer-font { 
 
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 
 
    font-size: 14px; 
 
    line-height: 1.42857143; 
 
    padding: 0 10px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script> 
 

 
<div ng-app="plunker" class="nicer-font"> 
 
    <div class="container"> 
 
    <p>Top level scope ID: {{$id}}</p> 
 
    <div data-repeatable> 
 
     Transcluded scope. $index = {{$index}}. Scope ID: {{$id}}, parent ID: {{$parent.$id}} 
 
    </div> 
 
    </div> 
 

 
    <script type="text/ng-template" id="template.html"> 
 
    <div ng-repeat="i in getTimes(5) track by $index" class="ng-repeat-scope"> 
 
     Template ng-repeat scope. $index = {{$index}}. Scope ID: {{$id}} 
 
     <div ng-transclude class="ng-transcluded-scope"></div> 
 
    </div> 
 
    </script> 
 
</div>

你也可以看到相同的演示on Plunkr如果你喜歡。