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

时间:2016-08-10 04:58:11

标签: angularjs

我是AngularJS的新人。

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

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

1)共享服务

2)使用事件

这是我已经签出的链接。

Can one controller call another

How do I inject a controller into another controller in 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');
  }
});
<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>

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

2 个答案:

答案 0 :(得分:7)

有几个原因导致您的代码段不起作用。

您没有实例化otherController因此根本无法执行任何代码。因此,您需要添加一个包含ng-controller="otherController"

的div

现在您拥有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');
  }
});
<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>

如果构建应用程序的方式阻止您嵌套控制器,则可以使用$ 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

答案 1 :(得分:0)

您发布的示例,如果您问为什么它不起作用,那是因为每个控制器都有自己的范围。您从'ShowDialog'发出myController并在otherController中进行检查。但ShowDialog只能在myController中使用emit。这就是我们在$rootScope上使用public override int GetHashCode() { return Id.GetHashCode(); } public override bool Equals(object input) { Thing comparee = input as Thing; return comparee != null && comparee.Id == Id; } public static bool operator ==(Thing self, Thing other) { return self != null && other != null && self.Id == other.Id; } public static bool operator !=(Thing self, Thing other) { return self == null || other == null || self.Id != other.Id; } 的确切原因,因为它是golbal并且可以在任何控制器中访问。

These are我所知道的几种方式来实现你所要求的。看看是否有帮助,请告诉我。