-
Notifications
You must be signed in to change notification settings - Fork 27.5k
feat($compile): explicitly request multi-element directive behaviour #5372
Conversation
I like this approach. I agree, there are too many other valid use cases for directives that end with -start or -end. |
Well, initial patch is up --- there are a few areas where I'm not sure of the best way to go
|
Edit: This is a good feature to have. Not all directives can handle multiple elements given to them, so it should be opt-in |
Some additional docs added for api/ng.$compile --- probably want some in the directive guide as well, and it's probably worded very poorly. |
+1 |
+1 for this PR!!! It really IS crazy to completely disable attributes that ends in |
+1. The current mechanism that completely invalidates directives ending with these special tokens is a serious oversight. What are we waiting for? |
since it's a breaking change, it might be hard to get it in before 1.3, and as mentioned it's possible that there are other directives which would benefit from the multiElement behaviour in angular core, which have not been changed in this PR yet. Also, since it's labeled as a 'feature', it's pushed pretty far back on the list of priorities |
By appending directive-start and directive-end to a directive it is now possible to have the directive act on a group of elements. It is now possible to iterate over multiple elements like so: <table> <tr ng-repeat-start="item in list">I get repeated</tr> <tr ng-repeat-end>I also get repeated</tr> </table>
We need this as well since swallowing the |
@@ -58,7 +58,7 @@ var ngBindDirective = ngDirective(function(scope, element, attr) { | |||
// jshint -W041 | |||
element.text(value == undefined ? '' : value); | |||
}); | |||
}); | |||
}, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't look right. ngBind shouldn't need this since it binds to textContent
LGTM. @mhevery ? |
element = jqLite(element[0].parentNode.childNodes); // reset because repeater is top level. | ||
expect(element.text()).toEqual('1A..1B;2A..2B;'); | ||
})); | ||
it('should group on nested groups of same directive', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This spec is grown a bit due to defining a custom directive, so that the same behaviour can be verified without the unexpected multi-element behaviour of the ngBind directive (re: #5372 (comment))
ngSwitch/ngSwitchWhen should also be opted-in... |
@IgorMinar I've determined that Anyways, I've updated and added some tests for the ng-switch multi-element behaviour which were missing previously, PTAL (To elaborate on the first paragraph, <p ng-switch-begin="text"><h1>Story</h1></p>
<!-- Can't require `ngSwitch` controller, throws, not a direct descendent -->
<p ng-switch-when="1">{{Page1}}</p>
<p ng-switch-when="2">{{Page2}}</p> <!-- ditto -->
<p ng-switch-when="3">{{Page3}}</p> <!-- ditto -->
<p ng-switch-end>FIN</p> |
Directives which expect to make use of the multi-element grouping feature introduced in 1.1.6 (angular@e46100f7) must now add the property multiElement to their definition object, with a truthy value. This enables the use of directive attributes ending with the words '-start' and '-end' for single-element directives. BREAKING CHANGE: Directives which previously depended on the implicit grouping between directive-start and directive-end attributes must be refactored in order to see this same behaviour. Before: ``` <div data-fancy-directive-start>{{start}}</div> <p>Grouped content</p> <div data-fancy-directive-end>{{end}}</div> .directive('fancyDirective', function() { return { link: angular.noop }; }) ``` After: ``` <div data-fancy-directive-start>{{start}}</div> <p>Grouped content</p> <div data-fancy-directive-end>{{end}}</div> .directive('fancyDirective', function() { return { multiElement: true, // Explicitly mark as a multi-element directive. link: angular.noop }; }) ```
Directives which expect to make use of the multi-element grouping feature introduced in 1.1.6 (angular@e46100f7) must now add the property multiElement to their definition object, with a truthy value. This enables the use of directive attributes ending with the words '-start' and '-end' for single-element directives. BREAKING CHANGE: Directives which previously depended on the implicit grouping between directive-start and directive-end attributes must be refactored in order to see this same behaviour. Before: ``` <div data-fancy-directive-start>{{start}}</div> <p>Grouped content</p> <div data-fancy-directive-end>{{end}}</div> .directive('fancyDirective', function() { return { link: angular.noop }; }) ``` After: ``` <div data-fancy-directive-start>{{start}}</div> <p>Grouped content</p> <div data-fancy-directive-end>{{end}}</div> .directive('fancyDirective', function() { return { multiElement: true, // Explicitly mark as a multi-element directive. link: angular.noop }; }) ``` Closes angular#5372 Closes angular#6574 Closes angular#5370 Closes angular#8044 Closes angular#7336
With regards to #5370, I think it's a bit crazy to completely disable the use of attributes/directives ending with
-start
or-end
.I would propose something like this:
And, instead of this:
we could have something like
then we could allow both multi-element attributes and attributes ending with
-start
and-end
, which I think would be nice.