0

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>
Danilo Cândido
  • 408
  • 1
  • 5
  • 18
  • Have you looked into using the `&` binding? See: https://stackoverflow.com/questions/16839259/angular-calling-controller-function-inside-a-directive-link-function-using – james00794 Nov 14 '17 at 19:33
  • Yea @james00794, but I have three *(selectedmealcalc, foodCalculation, $index)* parameters and they are populated inside the directive, one of these is $index. – Danilo Cândido Nov 14 '17 at 19:37
  • 1
    It doesn't matter that they are populated inside the directive - you are only passing the **names of the parameters** into the directive. So you would do something like: `` - now within the directive scope, you would call it like this: `removeFoodCalc({selectedMealCalc: mCalc, foodCalc: fCalc, index: $index})`. – james00794 Nov 14 '17 at 19:42

1 Answers1

2

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

james00794
  • 1,137
  • 7
  • 14