Can't call function inside custom directive. S

2019-08-31 10:55发布

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>

1条回答
Root(大扎)
2楼-- · 2019-08-31 11:06

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

查看更多
登录 后发表回答