-
Notifications
You must be signed in to change notification settings - Fork 27.5k
ngShow in directive with isolate scope is never shown #2500
Comments
If I had to guess exactly the problem it's because you have an isolate scope so it expects that ng-show will be bound inside the directive template and not outside of it. So as a quick-fix the following works if you put it inside your directive template instead:
However the whole point of the isolate scope is to isolate yourself from any direct bindings to the parent scope and instead pass them in. So arguably you should have something more like:
As for why ng-repeat is working fine, if I had to hazard another guess it is because it is part of the transclusion step. Since you are transcluding inside I do agree the behaviour is a bit non-intuitive, and I wonder if it wouldn't be better to ensure that binding to the parent scope always "just worked" regardless of an isolate scope or not. As a rule of thumb I try to design my directives to be completely ignorante (isolated) from the controller/scope that contains them. If necessary I'll write a controller inside the directive itself to manage the internal state of the directive. |
Agree, especially when you have multiple nested components, where you have to declare the "show" property on each one of them... So maybe when angular see an element directives with attribute directives, it should transclude just them.. Something like:
Before my-panel's template is compiled, it should transclude the other attributes on the HTML declaration. Is that possible? |
"I do agree the behaviour is a bit non-intuitive" There is also a Google Group for this: Lets find a solution... |
@shairez Unfortunately in that case, you have to wrap it in a div which has the ng-show directive. |
+1 to support ng-show on custom directives with isolated scope |
+1 It would be helpful somewhat declare inside directive statement that you want to use ng-show ng-hide on it. |
+1 |
+1; I just ran into this. |
+1... I don't think anybody placing attribute expressions on an element directive (at the point of use) is wanting them to run in the context of the isolate scope. |
+1 |
3 similar comments
+1 |
+1 |
+1 |
seems unnecessary to mention but i also would intuitively expect the isolate scope not to affect the other directives |
👍 |
2 similar comments
+1 |
👍 |
I agree with all of you, but if we had an isolated scope per attribute instead of the whole element, I am not sure of how easy would be having directives with options (via other attributes). I think that trying to do the hell of workarounds just for avoiding an extra div is overkill. |
But it's not just to avoid an extra div, how about trying to set focus into an input element that has type ahead. It's really hard to do it not hackily if you're using isolate scope. I guess the point is this affects more than just Ng-show On Wed, Aug 7, 2013 at 2:36 AM, Foxandxss notifications@github.com
|
Ah!, you got me 👍 |
I'm wondering if simply providing a way to reference to the parent scope (even though it technically isn't a parent) would help. |
@chrisnicola something like |
+1 |
This one keeps driving me nuts - I keep running into this and the only way to fix it is to add another div or make the scope not-isolated. |
Adding the following into the link function solves the problem. It's an extra step for the component creator, but makes the component more intuitive.
You'll also need to setup scope bindings for ngShow
|
Other languages use OOP inheritance to solve issues like this, for example, if you had |
OH yeah and... +1 ;) |
and another +1 |
Fixes issue with isolate scope leaking all over the place into other directives on the same element. Isolate scope is now available only to the isolate directive that requested it and its template. A non-isolate directive should not get the isolate scope of an isolate directive on the same element, instead they will receive the original scope (which is the parent scope of the newly created isolate scope). Paired with Tobias. BREAKING CHANGE: Directives without isolate scope do not get the isolate scope from an isolate directive on the same element. If your code depends on this behavior (non-isolate directive needs to access state from within the isolate scope), change the isolate directive to use scope locals to pass these explicitly. // before <input ng-model="$parent.value" ng-isolate> .directive('ngIsolate', function() { return { scope: {}, template: '{{value}}' }; }); // after <input ng-model="value" ng-isolate> .directive('ngIsolate', function() { return { scope: {value: '=ngModel'}, template: '{{value}} }; }); Closes angular#1924 Closes angular#2500
Fixes issue with isolate scope leaking all over the place into other directives on the same element. Isolate scope is now available only to the isolate directive that requested it and its template. A non-isolate directive should not get the isolate scope of an isolate directive on the same element, instead they will receive the original scope (which is the parent scope of the newly created isolate scope). Paired with Tobias. BREAKING CHANGE: Directives without isolate scope do not get the isolate scope from an isolate directive on the same element. If your code depends on this behavior (non-isolate directive needs to access state from within the isolate scope), change the isolate directive to use scope locals to pass these explicitly. // before <input ng-model="$parent.value" ng-isolate> .directive('ngIsolate', function() { return { scope: {}, template: '{{value}}' }; }); // after <input ng-model="value" ng-isolate> .directive('ngIsolate', function() { return { scope: {value: '=ngModel'}, template: '{{value}} }; }); Closes angular#1924 Closes angular#2500
Would it be more elegant to have another type of scope declaration that would allow access to isolate scope it it already exists or original scope if it doesn't? app.directive('MyDir', function(){ |
In a directive with an isolate scope with ng-show="someVar" (someVar from a parent ng-controller's $scope), the directive's tag is never shown ("display: none" isn't removed) (example). Other directives (like ng-repeat) bind values correctly in custom directives with isolate scope.
The text was updated successfully, but these errors were encountered: