Angular directive / child directive translates inside ng-repeat

The problem is that the child directive is bound to the parent, however the syntax {{name}} ignored by ng-repeat . What would be the right way to achieve this?

HTML (main / child directive)

 <compact-select no-item-selected-text="Add a Customer" no-item-selected-icon="fa-user" search-placeholder="Type a customer name" cs-model="customer" cs-items="contacts" > <display-item-template> <span>{{name}}</span> or <span>{{item.name}}</span> </display-item-template> </compact-select> 

Directive

 angular.module('core').directive('compactSelect', [function($timeout) { return { templateUrl : 'modules/core/views/components/compact-select-tpl.html', bindToController: true, transclude: true, scope: { noItemSelectedText: '@', noItemSelectedIcon: '@', csModel: '=', csItems: '=csItems' }, controllerAs : 'ctrl', controller : function($scope) { } }; }]).directive('displayItemTemplate', function($timeout) { return { require: '^compactSelect', restrict: 'E' } }); 

Directive template (modules / kernel / views / components / compact-select-tpl.html)

 <div class="compact-select-repeater-box" style="" > <div ng-transclude ng-repeat="item in ctrl.csItems | filter:searchParam" class="compact-select-repeater" ng-class="ctrl.getHighlightedClass(item)" ng-click="ctrl.itemSelected(item)"> <span>{{item.name}}</span> <span>{{item.id}}</span> </div> <div style="position:absolute;bottom:0"> <a href="#">+ Click here to add customer {{ctrl.message}}</a> </div> </div> 

I see what

 <span>{{item.name}}</span> <span>{{item.id}}</span> 

Gets a replacement for

 <span></span> or <span>{{item.name}}</span> 

, but not

 <span>{{name}}</span> or <span>{{item.name}}</span> 

Question: How do I get ng-repeat to respect the syntax of html bindings to the child directive? Or is there another way to achieve this?

+6
source share
2 answers

If I am not mistaken, you are trying to create a list view , so that the list template will be provided by the user, but the methods (click, etc.) will already be available through the directive.

Now, since angular 1.3 , the transcluded scope is a child of directive isolated scope ,

therefore, in your case, if you follow the correct hierarchy, you can access the directive scope from a template provided by the user.

Here is your area hierarchy:

directive isolated scopeng-repeat new scope for every rowtranscluded scope .

so if you want to access the directive scope from the transcluded scope , you will need to do $parent (for ng-repeat) and then access item.name , as shown below:

 <display-item-template> <span>Item Name: {{$parent.item.name}}</span> </display-item-template> 

In addition, you do not need bindings inside your compact-select-tpl , because you want this content to appear from shutdown:

 <div class="compact-select-repeater-box" style="" > <div ng-transclude ng-repeat="item in ctrl.csItems | filter:searchParam" class="compact-select-repeater" ng-class="ctrl.getHighlightedClass(item)" ng-click="ctrl.itemSelected(item)"> <!-- <span>{{item.name}}</span> <span>{{item.id}}</span> --> </div> <div style="position:absolute;bottom:0"> <a href="#">+ Click here to add customer {{ctrl.message}}</a> </div> </div> 
+8
source

The displayItemTemplate directive that you pass inside another directive already has interpolated data {{name}} and {{item.name}} .

If you do not have these variables in the $ scope, it will overlap the empty lines inside your intervals.

Then in your compactSelect directive, the div that gets transcluded will have its contents redefined.

If you move the displayItemTemplate directive inside another directive template, repetition will work. (you will need to remove ng (transclude and transclude: true

Fiddle

Also, if you use bindToController , do not put attributes in scope.

 function compactSelect() { return { template : [ '<div class="compact-select-repeater-box" style="" >', '<div ng-repeat="item in ctrl.csItems | filter:searchParam" class="compact-select-repeater" ng-class="ctrl.getHighlightedClass(item)" ng-click="ctrl.itemSelected(item)">', '<display-item-template>', '<span>{{item.name}}</span>', '</display-item-template>', '</div>', '<div style="position:absolute;bottom:0">', '<a href="#">+ Click here to add customer {{ctrl.message}}</a></div></div>', ].join(''), bindToController: { noItemSelectedText: '@', noItemSelectedIcon: '@', csItems: '=csItems' }, scope: {}, controllerAs : 'ctrl', controller : function($scope) { } } } function displayItemTemplate() { return { require: '^compactSelect', restrict: 'E' } } function SuperController() { this.name = "a name"; this.contacts = [{name:"rob"}, {name:"jules"}, {name:"blair"}]; } angular.module('myApp', []); angular .module('myApp') .controller('SuperController', SuperController) .directive('compactSelect', compactSelect) .directive('displayItemTemplate', displayItemTemplate); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script> <div ng-app="myApp"> <div ng-controller="SuperController as s"> <compact-select no-item-selected-text="Add a Customer" no-item-selected-icon="fa-user" search-placeholder="Type a customer name" cs-items="s.contacts"> </compact-select> </div> </div> 
+2
source

All Articles