118 votes

AngularJS appeler méthode le régulateur la directive de l’autre contrôleur

Je suis en train de celui-ci, mais il semble que google n'est pas mon ami, aujourd'hui je vais donc vous demander de vous les gars ici. Fondamentalement, je n'ai qu'une directive qui dispose de son propre contrôleur. Voir le code ci-dessous:

var popdown = angular.module('xModules',[]);

popdown.directive('popdown', function () {
    var PopdownController = function ($scope) {
        this.scope = $scope;
    }

    PopdownController.prototype = {
        show:function (message, type) {
            this.scope.message = message;
            this.scope.type = type;
        },

        hide:function () {
            this.scope.message = '';
            this.scope.type = '';
        }
    }

    var linkFn = function (scope, lElement, attrs, controller) {

    };

    return {
        controller: PopdownController,
        link: linkFn,
        replace: true,
        templateUrl: './partials/modules/popdown.html'
    }

});

C'est censé être un système de notification pour les erreurs/notifications/alertes. Ce que je veux faire, c'est à partir d'un autre contrôleur (pas une directive) pour appeler la fonction à afficher sur le contrôleur. Et lorsque je fais cela, je veux aussi mon lien fonctionne pour détecter que certaines propriétés changé, et effectuer certaines animations.

Voici un peu de code pour illustrer ce que je demande:

var app = angular.module('app', ['RestService']);

app.controller('IndexController', function($scope, RestService) {
    var result = RestService.query();

    if(result.error) {
        popdown.notify(error.message, 'error');
    }
});

Donc, lors de l'appel d' show sur le popdown directive contrôleur de la fonction de lien doit également être déclenchée et réaliser une animation. Comment pourrais-je y parvenir?

167voto

satchmorun Points 7504

C'est une question intéressante, et j'ai commencé à penser à comment je pourrais mettre en place quelque chose comme ça.

Je suis venu avec cette (violon);

En gros, au lieu d'essayer d'appeler une directive à partir d'un contrôleur, j'ai créé un module à la maison tous les popdown logique:

var PopdownModule = angular.module('Popdown', []);

J'ai mis deux choses dans le module, factory pour l'API qui peut être injecté n'importe où, et l' directive "pour définir le comportement de la réelle popdown élément:

L'usine juste définit un couple de fonctions success et error et conserve la trace d'un couple de variables:

PopdownModule.factory('PopdownAPI', function() {
    return {
        status: null,
        message: null,
        success: function(msg) {
            this.status = 'success';
            this.message = msg;
        },
        error: function(msg) {
            this.status = 'error';
            this.message = msg;
        },
        clear: function() {
            this.status = null;
            this.message = null;
        }
    }
});

La directive obtient l'API injecté dans son contrôleur, et les montres de l'api pour les changements (je suis en utilisant bootstrap css pour des raisons de commodité):

PopdownModule.directive('popdown', function() {
    return {
        restrict: 'E',
        scope: {},
        replace: true,
        controller: function($scope, PopdownAPI) {
            $scope.show = false;
            $scope.api = PopdownAPI;

            $scope.$watch('api.status', toggledisplay)
            $scope.$watch('api.message', toggledisplay)

            $scope.hide = function() {
                $scope.show = false;
                $scope.api.clear();
            };

            function toggledisplay() {
                $scope.show = !!($scope.api.status && $scope.api.message);               
            }
        },
        template: '<div class="alert alert-{{api.status}}" ng-show="show">' +
                  '  <button type="button" class="close" ng-click="hide()">&times;</button>' +
                  '  {{api.message}}' +
                  '</div>'
    }
})

Puis-je définir un app module qui dépend Popdown:

var app = angular.module('app', ['Popdown']);

app.controller('main', function($scope, PopdownAPI) {
    $scope.success = function(msg) { PopdownAPI.success(msg); }
    $scope.error   = function(msg) { PopdownAPI.error(msg); }
});

Et le code HTML ressemble à:

<html ng-app="app">
    <body ng-controller="main">
        <popdown></popdown>
        <a class="btn" ng-click="success('I am a success!')">Succeed</a>
        <a class="btn" ng-click="error('Alas, I am a failure!')">Fail</a>
    </body>
</html>

Je ne suis pas sûr si c'est complètement idéal, mais il semble que d'une manière raisonnable, afin d'établir la communication avec un global-ish popdown directive.

Encore une fois, pour référence, le violon.

26voto

Aron Points 725

Vous pouvez également utiliser les événements pour déclencher la Popdown.

Voici un violon basé sur satchmorun de la solution. Il évite la PopdownAPI, et le haut-contrôleur de niveau à la place $broadcasts "succès" et "erreur" des événements de la portée de la chaîne:

$scope.success = function(msg) { $scope.$broadcast('success', msg); };
$scope.error   = function(msg) { $scope.$broadcast('error', msg); };

Le Popdown module enregistre alors des fonctions de gestionnaire de ces événements, l'e.g:

$scope.$on('success', function(event, msg) {
    $scope.status = 'success';
    $scope.message = msg;
    $scope.toggleDisplay();
});

Cela fonctionne, au moins, et me semble être un bien découplé de la solution. Je vais laisser les autres carillon si cela est considéré comme une mauvaise pratique pour une raison quelconque.

11voto

luacassus Points 3189

Vous pouvez également exposer la directive du contrôleur à la portée parent, comme ngForm avec name d'attributs: http://docs.angularjs.org/api/ng.directive:ngForm

Ici vous pouvez trouver un exemple de base la façon dont il pourrait être atteint http://plnkr.co/edit/Ps8OXrfpnePFvvdFgYJf?p=preview

Dans cet exemple, j'ai l' myDirective avec contrôleur dédié avec $clear méthode de tri (de très simple API publique de la directive). Je peux publier ce contrôleur pour le parent et l'utilisation d'appeler cette méthode à l'extérieur de la directive.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X