I've created a directive in Angular that looks like this:
angular.module('msfApp')
.directive('listitem', function () {
return {
templateUrl: 'assets/templates/directives/listitem.html',
restrict: 'E',
scope: {
'item': '='
}
}
});
And the template looks like so:
<div class="tsProductAttribute" ng-click="toggleInBasket(item)">
<span class="tsProductAttribute-image">
<img ng-src="{{item.variants[0].image}}">
</span>
<span class="tsProductAttribute-desc">{{item.productName}}</span>
<span class="tsProductAttribute-price">{{item.variants[0].price[0].amount}} {{item.variants[0].price[0].entity}}</span>
</div>
But now I have two questions:
- The ng-click function doesn't fire in my controller,
toggleInBasket(item)
, why is that? - And secondly, how do I add a toggle behaviour to the list item so that it toggles a class called "tsProductAttribute--selected"
Thanks in advance guys!
I've created a directive in Angular that looks like this:
angular.module('msfApp')
.directive('listitem', function () {
return {
templateUrl: 'assets/templates/directives/listitem.html',
restrict: 'E',
scope: {
'item': '='
}
}
});
And the template looks like so:
<div class="tsProductAttribute" ng-click="toggleInBasket(item)">
<span class="tsProductAttribute-image">
<img ng-src="{{item.variants[0].image}}">
</span>
<span class="tsProductAttribute-desc">{{item.productName}}</span>
<span class="tsProductAttribute-price">{{item.variants[0].price[0].amount}} {{item.variants[0].price[0].entity}}</span>
</div>
But now I have two questions:
- The ng-click function doesn't fire in my controller,
toggleInBasket(item)
, why is that? - And secondly, how do I add a toggle behaviour to the list item so that it toggles a class called "tsProductAttribute--selected"
Thanks in advance guys!
Share Improve this question asked Jul 10, 2013 at 9:43 JoelJoel 3,1765 gold badges26 silver badges29 bronze badges3 Answers
Reset to default 121) Problem is the isolated scope. You cannot see the function in the controller scope. One solution is to pass the function reference to the directive:
http://plnkr.co/edit/GorcZZppa8qcIKbQAg2v?p=preview
<body ng-controller="ItemController">
<listitem item="item" item-click="toggleInBasket(item)"></listitem>
</body>
in the directive:
scope: {
'item': '=',
'itemClick': '&'
}
and in the template:
<div class="tsProductAttribute" ng-click="itemClick(item)">
2) Create another function in the directive to toggle selected state and call the controller function:
angular.module('msfApp').directive('listitem', function () {
return {
templateUrl: 'listitem.html',
restrict: 'E',
scope: {
'item': '=',
'itemClick': '&'
},
link: function(scope, iElement, iAttrs) {
scope.selected = false;
scope.toggleState = function(item) {
scope.selected = !scope.selected;
scope.itemClick(item);
}
}
}
});
and toggle the class in the template:
<div class="tsProductAttribute"
ng-class="{'tsProductAttribute--selected': selected}"
ng-click="toggleState(item)">
This is happening because you are using isolated scopes in the directive using scope: { 'item': '=' } which creates a new scope so your ng-click is not able to bind to controller function.
Kindly refer to below link to call parent function using ng-click
calling method of parent controller from a directive in AngularJS
@Macros answer made it work just fine for me! Here's my finished code:
Directive template file:
<div class="tsProductAttribute"
ng-class="{'tsProductAttribute--selected': selected}"
ng-click="toggleState(item)">
<span class="tsProductAttribute-image">
<img ng-src="{{variantImage}}">
</span>
<span class="tsProductAttribute-desc">{{item.productName}}</span>
<select ng-model="variantImage">
<option ng-repeat="variant in item.variants" value="{{variant.image}}">{{variant.name}} - {{variant.listprice.amount}}</option>
</select>
<span class="tsProductAttribute-price">{{item.variants[0].listprice.amount}} {{item.variants[0].listprice.entity}}</span>
</div>
Directive:
angular.module('msfApp')
.directive('listitem', function () {
return {
templateUrl: 'assets/templates/directives/listitem.html',
restrict: 'E',
scope: {
'item': '=',
'itemClick': '='
},
link: function(scope, iElement, iAttrs) {
scope.selected = false;
scope.toggleState = function(item) {
scope.selected = !scope.selected;
scope.itemClick(item);
}
}
}
});
Directive implementation:
<listitem item="item" item-click="toggleInBasket"></listiten>
Function in the Controller:
$scope.toggleInBasket = function(item) {
$scope.basket.toggle(item);
console.log(basket.get());
}