【问题标题】:AngularJS: How do I call a function defined in a directive's scope from a controller?AngularJS:如何从控制器调用指令范围内定义的函数?
【发布时间】:2015-03-22 17:35:33
【问题描述】:

我需要调用一个属于我的 Angular 应用程序中使用的 ng 指令的 $scope 的函数。

假设指令是这样定义的:

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

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

我需要从我的控制器(我们称之为 my-controller)调用 myFunction,这是放置我的指令的视图的控制器。

有可能吗? (最终修改指令)

编辑:提供的已经回答的问题(建议编辑)与我的类似,因为我不清楚,或者它显然没有解决我提出的具体问题。

编辑 2:从 Dan M. answer 开始(不考虑 mouseenter/mouseleave。只是试图让两个控制器相互通信),我通过$rootScope(因为两个控制器之间没有父子关系)by:

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

并通过以下方式接收它(在指令的控制器内):

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

但是在没有(见代码中的 cmets)事件被接收

【问题讨论】:

  • 我在问之前看到了那个答案。但是我不清楚,似乎给我的(简单)问题增加了一定程度的复杂性

标签: javascript angularjs angular-directive


【解决方案1】:

您可以在链接块内调用控制器函数。您还可以在指令中$emit 一个事件并在控制器中收听它(也许有一个用例)。

您似乎想在mouseenter 上调用它。您可以通过绑定到指令链接中的mouseenter 事件来做到这一点。问题是您需要 $apply 更改。 看看下面这段代码,它包含所有 3 个示例:http://jsbin.com/cuvugu/8/。 (也贴在下面)

提示:您可能需要注意如何命名指令。要将指令用作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}}"
  };
});

我还在 JS Bin 链接中包含了一个带有不同控制器的示例。这并没有真正改变任何东西,但这似乎是您问题的重要组成部分。这是代码块:

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}}"
  };
});

【讨论】:

  • 非常感谢丹。答案有点长,我现在专注于项目的不同部分。但我肯定会在接下来的几天内尝试您的解决方案,之后我会接受您的回答/提出其他问题
  • 首先我为迟到的反馈道歉。请在我的问题中查看我的“编辑 2”。再次感谢您
  • 我终于决定创建一个新问题。如果您愿意,请随时在那里回答,如果它解决了我的问题,我将很乐意接受。 stackoverflow.com/questions/29884608/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
相关资源
最近更新 更多