Reputation: 2086
I have a curious case that I can't figure out...
I have a directive on my app like so:
app.directive('cartTotal', function() {
return {
template: "<i ui-sref='cart' class='fa fa-shopping-basket'></i><span class='items'>@{{cartQTotal.total}}</span>"
};
});
When I load the page, this function fires:
if(localStorage.getItem("cart") != null)
{
console.log("makeacart");
var cart = JSON.parse(localStorage.getItem("cart"));
$scope.cartQTotal.total = 0;
for(i=0;i<cart.length;i++)
{
$scope.cartQTotal.total += cart[i].cartQ;
}
$('.fixed-cart').animateCss('bounce');
}
This works.
But if I modify $scope.cartQTotal outside of this, such as in a function (still in the parent controller but derived from an ng-click()
) for example:
$scope.add2Cart = function(name){
var cart = JSON.parse(localStorage.getItem("cart"));
for(var zz = 0;zz<cart.length;zz++)
{
if(cart[zz].item == name)
{
console.log("already in cart");
$('.fixed-cart').animateCss('bounce');
return;
}
}
cart.push({item:name,cartQ:1});
localStorage.setItem("cart", JSON.stringify(cart));
console.log("makeacartii");
$scope.cartQTotal.total = 0;
for(i=0;i<cart.length;i++)
{
$scope.cartQTotal.total += cart[i].cartQ;
}
console.log($scope.cartQTotal.total);//THE NUMBER I WANT
$('.fixed-cart').animateCss('bounce');
}
On //The Number I Want
line I get the proper number, as in the variable is correct but my directive template doesn't update. I don't understand why not.
Please assist.
Edit (from the docs):
Observing directives, such as double-curly expressions {{expression}}, register listeners using the $watch() method. This type of directive needs to be notified whenever the expression changes so that it can update the view.
So I guess the question is how do I notify the directive properly?
EDIT 2:
Looking at it using the nginspector extension, it appears I have two scopes with cartQTotal
rather than one, this remains constant whether or not I have the directive.
I am very confused because I have my controller scope and then a duplicate scope with all the same variables but the cartQTotal changes in one scope and not the other. Why would I have a duplicate but unnamed controller scope?
Upvotes: 0
Views: 302
Reputation: 2086
It was a problem as elucidated here: How do I share $scope data between states in angularjs ui-router?
Basically I didn't realize that my ui-router
configuration was creating a seperate instance of my controller. Changing my code as specified in that answer allowed it to work properly, even though I wasn't changing states it still affected the directive's ability to communicate with the proper controller instance.
Upvotes: 1
Reputation: 7739
This is because your directive and $scope
and the controller where data is updating both are different..
So you need to pass your controller data to your directive so that it will get modified. For this purpose you can use $broadcast
(but make sure you know about it because in large application its not good practice to use it).
So Try this Controller
cart.push({item:name,cartQ:1});
localStorage.setItem("cart", JSON.stringify(cart));
console.log("makeacartii");
$scope.cartQTotal.total = 0;
for(i=0;i<cart.length;i++)
{
$scope.cartQTotal.total += cart[i].cartQ;
}
console.log($scope.cartQTotal.total);//THE NUMBER I WANT
$('.fixed-cart').animateCss('bounce');
$rootScope.$broadcast("cartUpdated",$scope.cartQTotal);
directive
$scope.$on('eventEmitedName', function(event, data) {
$scope.cartQTotal = data;
});
Upvotes: 1
Reputation: 78
Data you wish to use within your directive that is manipulated outside of the directive should be passed in using bindings. There's a great short read here that shows you how. Personally, I use method 6 the most.
The gist is - you add to your directive's returned object:
scope: {
yourVariable: '=', //use =? for optional variables
}
And then use it in your directive as such:
<span>{{your-variable}}</span>
And bind to it as such:
<my-directive your-variable="myControllerVariable"></my-directive>
Upvotes: 0