【问题标题】:Call function from another controller using Events in AngularJS使用 AngularJS 中的事件从另一个控制器调用函数
【发布时间】:2016-12-16 07:34:49
【问题描述】:

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

请让我知道我缺少什么?最好的方法是什么?

【问题讨论】:

标签: angularjs


【解决方案1】:

您的 sn-p 不起作用有几个原因。

您没有实例化otherController,因此它根本无法执行任何代码。所以你需要添加一个带有ng-controller="otherController"的div

现在您有了 2 个控制器的实例,可以与 $scope 事件($emit、$broadcast、$on ) 它们需要嵌套,因为作用域事件取决于元素的层次结构。

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

$scope.$broadcast 会将事件注册到子控制器。

您可以通过将嵌套的 div 移出并更改事件类型来操作下面的 sn-p。

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.$on)

这就是说,将 $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

【讨论】:

    【解决方案2】:

    您发布的示例,如果您问它为什么不起作用,那是因为每个控制器都有自己的范围。您从myController 发出'ShowDialog' 并在otherController 中检查它。但ShowDialog 只能在myController 中使用。这就是我们在$rootScope 上使用emit 的确切原因,因为它是全局的,可以在任何控制器中访问。

    These are 我知道的几种方法可以实现您的要求。看看,如果有帮助,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-11
      • 1970-01-01
      • 2015-06-10
      相关资源
      最近更新 更多