Why doesn't ng-click work in my directive and how do I add a toggle class?

后端 未结 3 1954
清酒与你
清酒与你 2021-01-15 15:47

I\'ve created a directive in Angular that looks like this:

angular.module(\'msfApp\')
    .directive(\'listitem\', function () {
        return {
                    


        
相关标签:
3条回答
  • 2021-01-15 16:10

    1) 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)">
    
    0 讨论(0)
  • 2021-01-15 16:24

    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

    0 讨论(0)
  • 2021-01-15 16:27

    @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());
    
        }
    
    0 讨论(0)
提交回复
热议问题