当前位置: 首页 > 面试题库 >

角度模块中的全局通信:事件总线或中介器模式/服务

霍永年
2023-03-14
问题内容

到目前为止,我已经看到了许多解决问题的方法。当然,最简单的方法$emit将事件$rootScope作为事件总线使用,例如(https://github.com/btilford/anti-
patterns/blob/master/angular/Angular.md

angular.module('myModule').directive('directiveA', function($rootScope) {
  return {
    link : function($scope, $element) {
      $element.on('click', function(event) {
        $rootScope.$emit('directiveA:clicked', event);
      });
    }
  }
});
angular.module('myModule').directive('directiveB', function() {
  return {
    link : function($scope, $element) {
      $rootScope.on('directiveA:clicked', function(event) {
        console.log('received click event from directiveA');
      });
    }
  }
});






module.factory('MessageService',
  function() {
    var MessageService = {};

    var listeners = {};
    var count = 0;
    MessageService.registerListener = function(listener) {
      listeners[count] = listener;
      count++;

      return (function(currentCount) {
        return function() {
          delete listeners[currentCount];
        }
      })(count);
    }

    MessageService.broadcastMessage = function(message) {
      var keys = Object.keys(listeners);

      for (var i = 0; i < keys.length; i++) {
        listeners[keys[i]](message);
      }
    }

    return MessageService;
  }
);

问题是:

  • 在角度应用中使用第二个有什么意义吗?
  • 彼此之间的优缺点是什么?

问题答案:

在编写AngularJS应用程序时,创建自己的事件发射器实现会适得其反。Angular已经提供了基于事件的通信所需的所有工具。

  • 使用$emiton $rootScope可以很好地进行全局服务间通信,并且实际上没有任何缺点。
  • 使用$broadcast在自然范围(一个绑定到您的DOM的一部分)提供了视图组件(指令,控制器)之间范围的通信。
  • 使用$broadcaston可以$rootScope将前面的两点结合在一起(它提供了一个完全全球化的交流平台)。 这是基本上任何基于AngularJS的库都使用的解决方案

  • 如果您担心上一个选项的性能,并且确实希望使用单独的事件发射器,则可以通过创建一个独立的作用域($rootScope.$new(true))并$broadcast在其上使用轻松地创建事件发射器。(然后,您可以将其包装到服务中,然后将其注入所需的任何位置。)

最后一个选项创建一个集成到Angular中的成熟事件发射器(问题中提供的实现至少需要包装所有侦听器调用$apply()以正确集成),如果适合特定用途,还可以用于数据更改观察-
案件。

但是,除非您的应用程序真的很笨拙,或者您对事件名称冲突真的很偏执,否则前三个选项就足够了。

我不会详细介绍组件之间的其他通信方式。 一般而言,当情况要求使用范围共享数据,控制器直接交互或通过DOM Node属性进行通信时,您应该知道这一点。



 类似资料:
  • 在angular 2中,假设我有一条使用组件的路线: 现在,如果我直接导入组件,这就可以了: 但是我应该如何导入模块呢? 这不起作用,因为不是在模块文件中定义的,而是在组件文件中定义的。 以便组件加载模块的所有可用导入和声明? 根据@HristoKolev的建议,我在模块中添加了以下内容: 这允许路由从模块中查看基本表单组件。 但是,BasicForm组件似乎没有看到从NgMoules导入。特别是

  • 现在每个应用程序都必须处理实体的更新功能。而不是在n个应用程序模块中实现更新功能。我想在Spring启动中构建一个通用接口或服务器。 我的问题是如何设计可用于上述场景的服务/接口。任何api或工具,可以帮助我实现这一点。我不想在每个应用程序模块中编写更新代码。 提前感谢。

  • 这个问题更倾向于范式。为什么我们不在 MVP 环境中使用事件总线而不是侦听器?通常,“P”部件具有视图和模型引用的依赖关系注入。当然,这有一个优点,即通过表示器显示视图和模型之间的显式契约,这更具可读性。 但是,让演示者侦听来自视图的事件并且事件携带视图负载(例如:json表示形式)不是一种更干净的方法吗?演示者回过头来对视图说话也是如此。视图将侦听来自演示者的事件。主要优点是,我们不必为视图和表

  • 问题内容: 我想可能有许多角度模块连接到一个shellpage中的不同区域。但是AngularJS中的模块可以彼此“交谈”吗?如果是,怎么办? 问题答案: 模块可以通过多种方式进行交互或共享信息 可以将一个模块注入另一个模块,在这种情况下,容器模块可以访问已注入模块的所有元素。如果您查看有角的种子项目,则会为指令,控制器,过滤器等创建模块,就像这样 angular.module(“ myApp”,

  • 本文向大家介绍Erlang中的模块与模式匹配介绍,包括了Erlang中的模块与模式匹配介绍的使用技巧和注意事项,需要的朋友参考一下 模块是Erlang的基本代码单元,erl文件编译后以.beam作为扩展名,采用UTF8字符集,.erl文件示意如下: -module(模块名,与存放模块的文件名相同) -export([方法名/输入参数的个数]) 模块属性有两种类型:预定义型和用户定义型。   Erl

  • 我部署了一个定义了远程EJB的全局模块,但我无法从部署的应用程序访问它们。 以下是界面: 既然默认的@Ejb找不到bean,我如何找到部署的Ejb的jndi名称?值得一提的是,jboss cli中的/subsystem=naming:jndi-view()没有打印任何关于已部署模块的信息,并且在wildfly日志中没有错误。 也许,在全局模块中定义可注入ejbs是不可能的?