javascript - AngularJS parent directive scope from inner ng-transclude -
i print index of ng-repeat iterator of parent directive. pseudo code:
index.html
<div data-repeatable> {{$index}} not display </div>
template.html
<div ng-repeat="i in gettimes(5) track $index"> {{$index}} displays correctly <div ng-transclude></div> </div>
app.js
// other code omitted .directive('repeatable', function() { return { scope: {}, transclude: true, templateurl: 'template.html' }; })
i've explored many different approaches/tweaks, nothing has worked far. appreciated!
thanks.
okay, may hacky, , rely on internal implementation details angularjs might pulled in version, still... here way found work.
note appears work in angular 1.3 branch.
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 = []; (var = 1; <= n; i++) arr.push(i); return arr; }; // needs done in $applyasync ng-repeat has // time render items scope.$applyasync(function() { // using transclude function hold of 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 $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>
you can see same demo on plunkr if prefer.
Comments
Post a Comment