Reputation: 319
How would I get my directive to update properly based on a variable on the parent of the parent's scope?
I have an animation directive that I want to use for showing loading for individual grids of data that will need to be populated by doing a service call. I currently have a main template for a page and I have an ng-include for a certain "widget" I want to show on the page. The widget will either show the div with the populated information or the loading directive will show, at least that's what I was trying to get it to do.
The $watch I have going on doesn't seem to be working either, i've put some log statements in there and I manually change the variable that "test" is pointing to, yet it acts as if it was never changed.
//One approach to the directive
myApp.directive('loading', function() {
return {
restrict: "E",
scope : {
test : '='
},
templateUrl: 'partials/loading-animation.html'
};
});
The html for the include, which includes the directive also. loadVal is a variable on the scope of the parent's parent controller. loadVal changes based on a service call and is updated properly.
<div ng-show="!loadVal" class='address store'>
<span>{{address.storeName}}</span>
<span>{{address.address1}}</span>
<span>{{address.city}},{{address.state}} {{address.zip}}</span>
</div>
<loading test="loadVal" ng-show="test"></loading>
Right now, if I just have the directive only, it still does not show up. I have tried it using ng-switch, but since there's no route change it shows both the loading directive and the address information. I've also tried showing either based on whether one is true or false (!loadVal and loadVal), the problem is though it doesn't seem to know what "!loadVal" is because it never displays the html that ng-show="!loadVal" is on.
Edit: Looks like I got it working just fine, here's a plnkr showing what I was trying to achieve: Plnkr
Note: I noticed I can't reference the parent of the parent's scope with ng-show (i.e ng-show="loadVal") on the directive template. However, if I make a new variable and have the scope be bi-directional and set that variable equal to loadVal, then it picks up the changes.
Upvotes: 0
Views: 354
Reputation: 405
First of all, it appears that you are trying to access the test
property of the loading
directive's isolate scope in the ng-show
directive. (<loading test="loadVal" ng-show="test"></loading>
) That's not going to work. What ng-show
is actually trying to bind to in your code is $scope.test
in the parent scope. If you want to use the directive scope's test
property for visibility, use it in your template.
Also, there is no need to use $watch in your directive as it stands right now and you should almost never need to use scope.$apply()
for changes to scope properties. AngularJS wraps most of your code inside an $apply
call for you.
Try this:
myApp.directive('loading', function() {
return {
restrict: "E",
replace: true,
scope : {
test : '='
},
template: '<div ng-show="test"></div>'
};
});
I replaced the templateUrl with an inline template just for demo purposes.
The loading
directive in the view can be simplified to <loading test="loadVal"></loading>
.
Upvotes: 1