Call method in directive controller from other controller

后端 未结 4 1801
轮回少年
轮回少年 2020-12-02 03:28

I have a directive that has its own controller. See the below code:

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

popdown.directive(\'popdown\', function (         


        
相关标签:
4条回答
  • 2020-12-02 04:02

    You can also use events to trigger the Popdown.

    Here's a fiddle based on satchmorun's solution. It dispenses with the PopdownAPI, and the top-level controller instead $broadcasts 'success' and 'error' events down the scope chain:

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

    The Popdown module then registers handler functions for these events, e.g:

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

    This works, at least, and seems to me to be a nicely decoupled solution. I'll let others chime in if this is considered poor practice for some reason.

    0 讨论(0)
  • 2020-12-02 04:06

    I got much better solution .

    here is my directive , I have injected on object reference in directive and has extend that by adding invoke function in directive code .

    app.directive('myDirective', function () {
        return {
            restrict: 'E',
            scope: {
            /*The object that passed from the cntroller*/
            objectToInject: '=',
            },
            templateUrl: 'templates/myTemplate.html',
    
            link: function ($scope, element, attrs) {
                /*This method will be called whet the 'objectToInject' value is changes*/
                $scope.$watch('objectToInject', function (value) {
                    /*Checking if the given value is not undefined*/
                    if(value){
                    $scope.Obj = value;
                        /*Injecting the Method*/
                        $scope.Obj.invoke = function(){
                            //Do something
                        }
                    }    
                });
            }
        };
    });
    

    Declaring the directive in the HTML with a parameter:

    <my-directive object-to-inject="injectedObject"></ my-directive>
    

    my Controller:

    app.controller("myController", ['$scope', function ($scope) {
       // object must be empty initialize,so it can be appended
        $scope.injectedObject = {};
    
        // now i can directly calling invoke function from here 
         $scope.injectedObject.invoke();
    }];
    
    0 讨论(0)
  • 2020-12-02 04:11

    You could also expose the directive's controller to the parent scope, like ngForm with name attribute does: http://docs.angularjs.org/api/ng.directive:ngForm

    Here you could find a very basic example how it could be achieved http://plnkr.co/edit/Ps8OXrfpnePFvvdFgYJf?p=preview

    In this example I have myDirective with dedicated controller with $clear method (sort of very simple public API for the directive). I can publish this controller to the parent scope and use call this method outside the directive.

    0 讨论(0)
  • 2020-12-02 04:21

    This is an interesting question, and I started thinking about how I would implement something like this.

    I came up with this (fiddle);

    Basically, instead of trying to call a directive from a controller, I created a module to house all the popdown logic:

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

    I put two things in the module, a factory for the API which can be injected anywhere, and the directive for defining the behavior of the actual popdown element:

    The factory just defines a couple of functions success and error and keeps track of a couple of 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;
            }
        }
    });
    

    The directive gets the API injected into its controller, and watches the api for changes (I'm using bootstrap css for convenience):

    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>'
        }
    })
    

    Then I define an app module that depends on 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); }
    });
    

    And the HTML looks like:

    <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>
    

    I'm not sure if it's completely ideal, but it seemed like a reasonable way to set up communication with a global-ish popdown directive.

    Again, for reference, the fiddle.

    0 讨论(0)
提交回复
热议问题