Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining ng-repeat and a directive denies the transcluded content access to outer scope?

Scenario

In my application, I have several occurrences of a list of items. I can insert new items by clicking a plus button above or below the item. I can delete an item by clicking the minus button on an item. I call this a "plus minus list" or "add remove list".

Existing Solution

Currently, I manage the adding and removing of items with a single delegate click handler per list, which is managed by the controller, in violation of good AngularJS style. I wish to place this logic in a custom directive. Furthermore, there is some scaffolding on each item (the plus and minus buttons, for example) that could be hidden inside a directive's template.

Specific Problem

When using a custom directive in combination with ng-repeat, transcludion, defined scope, and likely other things in the fairly convoluted system that is Angular custom directives, various things that intuitively should be accessible appear to be unavailable. Namely: the whole point of transclusion is to have access to the parent scope inside a directive.

If the directive template includes the ng-transclude tag inside of an ng-repeat, the transcluded content does not appear to retain its access to the outer scope (the application's scope, not the directive's scope). Yet, if this is done without the use of a directive (a bare ng-repeat) or if the directive has no ng-repeat, access works as expected.

Simplified Example

I have made a demo of the issue, showing all three cases:

http://plnkr.co/edit/np6lTmeTrKioo4kb8SP6?p=preview

Note that the green 'outer scope data' does not appear when a transcluding directive contains an ng-repeat. The data that is passed through explicitly (the fields) binds as expected, but the point of transclusion is that we do not have to explicitly pass all data that might be bound.

I'm using AngularJS 1.2.0-rc.3.

Previous Attempts

I have spent all day on this. I haven't seen anyone with exactly my scenario: there was usually some subtle reason why the transclusion wasn't required or they wished to access the parent scope inside the directive itself. I'm almost 100% certain that this is a subtle scope-related issue, and I don't know Angular well enough to resolve the subtly. Lacking better direction, I have already tried (at random) many combinations of the different forms of directive scope, transclude, and replace with predictably few results.

like image 287
Dwight Avatar asked Dec 19 '25 19:12

Dwight


1 Answers

A few new SO questions began coming up in searches after I wrote this question, so it looks like this question is actually incredibly common. Here's an example:

AngularJS isolated directive with ng-repeat breaks transclusion scope

The transcluded scope becomes the child of the ng-repeat's scope, rather than the outer scope, because ng-repeat creates scope. So far, my searching has not been able to reveal why ng-repeat actually needs a scope. Given how common this specific use case is, I wonder if Angular may enable this type of construction in the future.

like image 99
Dwight Avatar answered Dec 24 '25 10:12

Dwight