简体   繁体   English

AngularJS:如何从控制器调用在指令范围内定义的函数?

[英]AngularJS: How do I call a function defined in a directive's scope from a controller?

I need to call a function which belongs to the $scope of a ng-directive used in my Angular application. 我需要调用一个函数,该函数属于Angular应用程序中使用的ng指令的$ scope。

Let's say the directive is defined like this: 假设指令的定义如下:

.directive('my-directive', ['$document', '$timeout', function ($document, $timeout) {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            // ....
        },
        controller: ['$scope', function ($scope) {

            $scope.myFunction= function (mouseEnter) {
                // ...
            };
        }
    };
}]);

I need to call myFunction from my controller (let's call it my-controller ) which is the controller of the view where my directive is placed. 我需要从我的控制器(称为我的控制器 )调用myFunction ,该控制器是放置我的指令的视图的控制器。

Is it possible to do it? 有可能做到吗? (eventually modifying the directive) (最终修改指令)

EDIT : The already answered question provided (proposed for edit) is similar to mine by it's not clear to me or it doesn't apparently solve the specific problem I proposed. 编辑 :提供的已经回答的问题(建议进行编辑)与我的问题类似,因为我不清楚,或者它显然无法解决我提出的特定问题。

EDIT 2 : starting from Dan M. answer (without taking mouseenter/mouseleave in consideration. just trying to make the two controllers communicate with each other), I broadcasted my event to my directive's controller through $rootScope (as there is there is no parent-child relation between the two controllers) by: 编辑2 :从Dan M.答案开始(不考虑mouseenter / mouseleave。仅试图使两个控制器相互通信),我通过$ rootScope将事件广播到指令的控制器(因为没有父级) -两个控制器之间的子关系):

console.log("let's broadcast the event.."); // this is printed
$rootScope.$broadcast('callDirectiveControllersFunction'); // I even tried with $scope in place of $rootScope and $emit in place of $broadcast

and by receving it (within the directive's controller) by: 并通过以下方式将其删除(在指令的控制器内):

var myFunction = function(){
   // ...
}

$scope.$on('callDirectiveControllersFunction', function (){
   console.log("event received"); // this is not printed
   callMyFunction(); 
});
// I even tried using $rootScope in place of $scope

However in no case (see comments in code) the event is received 但是在任何情况下 (请参见代码中的注释)都不会收到该事件

You can call a controller function inside the link block. 您可以在链接块内调用控制器函数。 You can also $emit an event in the directive and listen to the it in the controller (maybe there is a use case for that). 您也可以在指令中$ emit一个事件,并在控制器中监听该事件(也许有一个用例)。

It seems that you want to call it on mouseenter . 看来您想在mouseenter上调用它。 You can do that by binding to the mouseenter event in the directive link. 您可以通过绑定到指令链接中的mouseenter事件来实现。 The catch is you need to $apply the changes. 问题是您需要$应用更改。 Take a look at the following piece of code, which contains all 3 examples: http://jsbin.com/cuvugu/8/ . 看一下下面的代码,其中包含所有3个示例: http : //jsbin.com/cuvugu/8/ (also pasted below) (也粘贴在下面)

Tip: You might want to pay attention to how you name your directives. 提示:您可能要注意指令的命名方式。 To use a directive as my-directive you need to name it as myDirective . 要将指令用作my-directive您需要将其命名为myDirective

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

app.directive('myDirective', function () {
  function directiveLink(scope){
    scope.$emit('customEvent');
  }

  return {
    restrict: 'EA',
    scope: {},
    link: directiveLink,
    controller: function ($scope) {
      $scope.bar = 'bar';
      $scope.myFunction = function () {
        $scope.bar = 'foobar1';
      };

      $scope.$on('customEvent', function (){
        $scope.myFunction();
      });
    },
    template: "Foo {{bar}}"
  };
});

app.directive('anotherDirective', function () {
  function directiveLink(scope){
    scope.myFunction();
  }

  return {
    restrict: 'EA',
    scope: {},
    link: directiveLink,
    controller: function ($scope) {
      $scope.bar = 'bar';
      $scope.myFunction = function () {
        $scope.bar = 'foobar2';
      };
    },
    template: "Foo {{bar}}"
  };
});

app.directive('mouseDirective', function () {
  function directiveLink(scope, element){
    element.bind('mouseenter', function(){
      scope.$apply(function(){
        scope.myFunction();
      });
    });

    element.bind('mouseleave', function(){
      scope.$apply(function(){
        scope.myOtherFunction();
      });
    });
  }

  return {
    restrict: 'EA',
    link: directiveLink,
    controller: function ($scope) {
      $scope.bar = 'no';
      $scope.myFunction = function () {
        $scope.bar = 'yes';
      };

      $scope.myOtherFunction = function () {
        $scope.bar = 'no';
      };
    },
    template: "Mouse Enter: {{bar}}"
  };
});

I also included an example with a distinct controller in the JS Bin link. 我还在JS Bin链接中包含了一个具有不同控制器的示例。 That doesn't really change anything, but it seems to be an important part of your question. 那并没有真正改变任何东西,但这似乎是您问题的重要组成部分。 Here's the code block: 这是代码块:

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

app.controller('myController', function($scope){
  $scope.bar = 'foo';

  $scope.myFunction = function(){
    $scope.bar = 'foobar3';
  };
});

app.directive('lastDirective', function () {
  function directiveLink(scope){
    scope.myFunction();
  }

  return {
    restrict: 'EA',
    scope: {},
    link: directiveLink,
    controller: 'myController',
    template: "Foo {{bar}}"
  };
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM