Home Can't call function inside custom directive. Scope is not what I want to use
Reply: 1

Can't call function inside custom directive. Scope is not what I want to use

Danilo Cândido
1#
Danilo Cândido Published in 2017-11-14 19:16:15Z

I used to have this inside my html 'calculations-td-plan.html'

<tr ng-repeat="foodCalculation in selectedMealCalc.calculated_foods">
          <td>{{foodCalculation.food.name}}</td>
          <td>{{foodCalculation.gram_amount}} g</td>
          <td>{{foodCalculation.kcal}} kcal</td>
          <td>{{foodCalculation.proteina}} g</td>
          <td>{{foodCalculation.cho}} g</td>
          <td>{{foodCalculation.lipideos}} g</td>
          <td class="text-center">
            <button class="btn btn--principal btn--xs" ng-click="edtiFoodCalc(selectedmealcalc, foodCalculation, $index)">Editar</button>
            <button class="btn btn--principal btn--xs" ng-click="removeFoodCalc(selectedmealcalc, foodCalculation)">Remover</button>
          </td>
        </tr>

Then I create a directive like above.

<div class="row">
  <div class="col-md-12" ng-show="( items | filter: { food_option: option } ).length > 0">
    Opção {{ option }}
    <table class="table table-calculo table-striped">
      <thead>
        <tr>
          <th>Alimento</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="foodCalculation in ( items | filter: { food_option: option } ) track by $index">
          <td>{{foodCalculation.food.name}}</td>
          <td class="text-center">
            <button class="btn btn--principal btn--xs" ng-click="edtiFoodCalc(selectedmealcalc, foodCalculation, $index)">Editar</button>
            <button class="btn btn--principal btn--xs" ng-click="removeFoodCalc(selectedmealcalc, foodCalculation)">Remover</button>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

And I call this diretive inside 'calculations-td-plan.html' as

<div ng-repeat="option in [0,1,2,3,4]">
    <meal-option option="{{option}}"
                 items="selectedMealCalc.calculated_foods"
                 selectedmealcalc="selectedMealCalc"></meal-option>
</div>

And this is my directive JS.

'use strict';

angular.module('nutriApp').directive('mealOption', ['$compile', function($compile) {
  var mealOption = {
    restrict: 'E',
    templateUrl: 'views/checkins/meal-options.html',
    require: 'foodSelector',
    scope: {
      option: "@",
      items: "=",
      selectedmealcalc: "="
    }
  };

  mealOption.controller = ['$scope', 'Food', function($scope, Food) {
    $scope.sumFood = {};
    $scope.summerizeOption = function(foods) {
      if(foods.length > 0){
          $scope.sumFood = Food.summerize(foods);
      }
    };
  }];

  return mealOption;

}]);

But now the funcions that I am calling edtiFoodCalc and removeFoodCalc are not working.

When I put ng-controller in my directive it works, (Only call the method) but I can't get the same scope.

<div class="row" ng-controller="CheckinsPlansCtrl">

I am trying to edit with edtiFoodCalc and I am not getting the result that I want. I think ng-controller creates new scopes when I do ng-repeat, and when I did not have a directive the code worked.

<div ng-repeat="option in [0,1,2,3,4]">
        <meal-option option="{{option}}"
                     items="selectedMealCalc.calculated_foods"
                     selectedmealcalc="selectedMealCalc"></meal-option>
    </div>
james00794
2#
james00794 Reply to 2017-11-15 16:56:11Z

You can use angular's & binding, which allows the directive's scope to pass values back to the parent scope. These values don't need to be defined in the controller - they can be defined in the directive and then sent back to the controller.

For example, given a controller and directive:

// Controller
app.controller('MainCtrl', function($scope) {  
  $scope.funcA = function(value, index) {
    console.log("Called funcA from " + value + " with index " + String(index));
  };

  $scope.funcB = function(value, index) {
    console.log("Called funcB from " + value + " with index " + String(index));
  }
});

// Directive
app.directive('arrayDirective', function() {
  return {
    templateUrl: "array_directive.html",
    scope: {
      controllerFuncA: "&controllerFuncA",
      controllerFuncB: "&controllerFuncB"
    },
    link: function (scope, element, attr) {
      scope.items = ["a","b","c","d","e"];

      scope.callControllerFuncA = function(i) {
        console.log("Calling controller funcA!");
        scope.controllerFuncA({from: "directive", index: i});
      };

      scope.callControllerFuncB = function(i) {
        console.log("Calling controller funcB!");
        scope.controllerFuncB({from: "directive", index: i});
      };   
    }
  };
});

And the following templates:

<!-- Controller template -->
<body ng-controller="MainCtrl">
  <array-directive controller-func-a="funcA(from, index)" controller-func-b="funcB(from, index)"></array-directive>
</body>

<!-- Directive template -->
<div>
  <div ng-repeat="item in items">
    <div>{{item}}</div> 
    <div><a href="#" ng-click="callControllerFuncA($index)">Call Controller Func A</a></div>
    <div><a href="#" ng-click="callControllerFuncB($index)">Call Controller Func B</a></div>
  </div>
</div>

You can then use controllerFuncA and controllerFuncB from within the directive to call the corresponding parent controller functions, funcA and funcB. Note that these directive functions take an object as the parameter, where the keys of the object correspond to the keys that you passed into the directive on the <array-directive> tag.

See the attached fiddle and watch the developer console for the complete example: https://plnkr.co/edit/3h8J00ndBk4OQ16C8hf2

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.329694 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO