使用AngularJS中的事件从另一个控制器调用函数

Nir*_*ani 3 angularjs

我是AngularJS的新人.

我试图从另一个控制器调用函数.

我发现有很多方法可以做到这一点.

1)共享服务

2)使用事件

这是我已经检查过的链接.

一个控制器可以调用另一个

如何将控制器注入AngularJS中的另一个控制器

我认为使用事件是更好的方法.除此之外,我认为当我们使用$ rootscope时,它不会破坏事件参考权吗?

var myModule = angular.module('myapp', []);

myModule.controller('otherController', function($scope) {
  $scope.$on('ShowDialog', function(event) {
    alert("hello");
  });
});

myModule.controller('myController', function($scope) {
  $scope.OnClick = function() {
    alert("Done");
    $scope.$emit('ShowDialog');
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div style="padding: 0 5px; height: 100%" ng-app="myapp">
  <div style="padding: 0 5px; height: 100%" ng-controller="myController">
<input type="button" ng-click="OnClick()" value="Say Hello!" />
    </div>
  </div>
Run Code Online (Sandbox Code Playgroud)

请让我知道我错过了什么?什么是最好的方法呢?

gyc*_*gyc 7

您的代码段不起作用有几个原因.

你没有实例化,otherController所以它根本不会执行任何代码.所以你需要添加一个divng-controller="otherController"

现在您有了2个控制器的实例,要与$ scope事件($ emit,$ broadcast,$ on)进行通信,它们需要嵌套,因为范围事件取决于元素的层次结构.

$ scope.$ emit将事件注册到父控制器.

$ scope.$ broadcast将向子控制器注册事件.

您可以通过移动嵌套的div并更改事件类型来操作下面的代码段.

var myModule = angular.module('myapp', []);

myModule.controller('otherController', function($scope) {
  $scope.$on('ShowDialog', function(event) {
    alert("hello");
  });
});

myModule.controller('myController', function($scope) {
  $scope.OnClick = function() {
    alert("Done");
    $scope.$broadcast('ShowDialog');
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div style="padding: 0 5px; height: 100%" ng-app="myapp">
  <div style="padding: 0 5px; height: 100%" ng-controller="myController">
    <input type="button" ng-click="OnClick()" value="Say Hello!" />
    <div ng-controller="otherController"></div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

如果构建应用程序的方式阻止您嵌套控制器,则可以使用$ rootScope事件.

他们的工作方式如下:

$ rootScope.$ broadcast将向rootScope和范围广播事件.这将使您的代码变得非常快速,因为任何控制器的任何范围都可以监视此事件.

$ rootScope.$ emit是首选,因为它在事件应用程序范围内注册并仅使其可用于rootScope.($ rootScope.$上)

这就是说,使用$ scope或$ rootScope事件进行简单的数据操作被认为是不好的做法,这些操作在应用程序范围内没有意义.

例如,您想要告诉您的应用程序用户已经注销,那么将它作为一个整体广播到应用程序是有意义的.

但是,如果您只想让1个控制器知道已经加载了一些随机数据,那么就使用服务.(例如:统计控制器不需要知道用户已经更改了他的个人资料图片)

这被认为是不好的做法,因为你最终将从不同的控制器注册许多事件,你将有冲突的事件名称,最终将很难维护.

如果你仍然想坚持事件,你应该记得解开它们,否则你会遇到内存泄漏问题和其他令人讨厌的错误:

var unbind = $rootScope.$on('logout', function(event, data) {
    console.log('LOGOUT', data);
});
$scope.$on('$destroy', unbind); //when your controller is unloaded, unbind the events
Run Code Online (Sandbox Code Playgroud)