web-dev-qa-db-fra.com

Fonction d'appel sur la portée parent directive avec l'argument de portée directive

Je développe une directive qui montre et cache son contenu basé sur un événement click (ng-click) défini dans son modèle. Sur certaines vues où la directive est utilisée, j'aimerais pouvoir savoir si la directive affiche ou masque actuellement son contenu afin que je puisse répondre aux modifications du DOM. La directive a une portée isolée et j'essaie d'avertir la portée parent lorsque la directive a été "basculée". J'essaie d'accomplir cela en passant une fonction de rappel à la directive où elle est utilisée et qui peut être appelée lorsque l'état de la directive change, c'est-à-dire masque ou affiche

Je ne sais pas comment implémenter correctement ceci étant que l'état de la directive (caché ou affiché) est stocké dans la portée isolée de la directive et est déterminé après le ng-click. Par conséquent, je dois appeler la fonction de la portée parent à partir de la directive et non à partir de la vue.

Cela rendra WAAY plus logique avec un exemple. Voici un plunk démontrant ce que j'aimerais faire:

http://plnkr.co/edit/hHwwxjssOKiphTSO1VIS?p=info

var app = angular.module('main-module',[])

app.controller('MainController', function($scope){
  $scope.myValue = 'test value';
  $scope.parentToggle = function(value){
    $scope.myValue = value;
  };
});

app.directive('toggle', function(){
    return {
            restrict: 'A',
            template: '<a ng-click="toggle();">Click Me</a>',
            replace: true,
            scope: {
                OnToggle: '&'
            },
            link: function($scope, elem, attrs, controller) {
                $scope.toggleValue = false;
                $scope.toggle = function () {
                    $scope.toggleValue = !$scope.toggleValue;
                    $scope.OnToggle($scope.toggleValue)
                };
            }
        };
});

Je suis relativement nouveau sur Angular. Est-ce une mauvaise idée pour commencer? Dois-je utiliser un service ou quelque chose plutôt que de transmettre des références de fonction?

Merci!

29
Nick

Mise à jour

Vous pouvez également utiliser & Pour lier la fonction de la portée racine (c'est en fait le but de &).

Pour ce faire, la directive doit être légèrement modifiée:

app.directive('toggle', function(){
  return {
    restrict: 'A',
    template: '<a ng-click="f()">Click Me</a>',
    replace: true,
    scope: {
      toggle: '&'
    },
    controller: function($scope) {
      $scope.toggleValue = false;
      $scope.f = function() {
        $scope.toggleValue = !$scope.toggleValue;
        $scope.toggle({message: $scope.toggleValue});
      };
    }
  };
});

Vous pouvez utiliser comme ceci:

<div toggle="parentToggle(message)"></div>

Plunk


Vous pouvez lier la fonction en utilisant =. De plus, assurez-vous que le nom de la propriété dans votre portée et votre balise correspond (AngularJS traduit CamelCase en notation tiret).

Avant:

scope: {
  OnToggle: '&'
}

Après:

scope: {
  onToggle: '='
}

De plus, n'utilisez pas on-toggle="parentToggle({value: toggleValue})" dans votre modèle principal. Vous ne voulez pas appeler la fonction mais simplement passer un pointeur de la fonction à la directive.

Plunk

50
Sebastian