如何跟踪AngularJS中的事件?

Jos*_*eam 5 angularjs

我有一个包含项目的应用程序,您可以执行诸如添加新项目,更新项目文本,将项目移动到其他文件夹等操作.

我有一个items工厂保持的阵列内的所有项目,如普通的对象,并且工厂返回具有各种方法,如一个单get(),set()

为了在问题中添加一些上下文,我也在使用Node.js和MongoDB.

无论如何,由于我的一切,就像各种工厂items,folders和所有不同意见的各种控制器,我严重的事件依赖.举一些例子:

// items factory
update: function(params) {
    // add to database, then...
    .then(function() {
        $rootScope.$emit('itemCreated');
    });
}
Run Code Online (Sandbox Code Playgroud)

// items controller

// I need to refresh the items list in the scope
$rootScope.$on('itemCreated', function() { // when an item is added to the database
    $scope.items = items.getAll(); // retrieve all items from the items factory
});
Run Code Online (Sandbox Code Playgroud)

这些是他们自己的事件"子集",因为它们都与项目的"CRUD"操作有关.

但是,我也有其他事件.例如,我有一个侦听任何请求和响应的拦截器.我有一个使用指令的加载小部件(旋转轮的图像).该指令将在请求开始时显示加载小部件,并在请求结束时隐藏加载小部件.这也是基于事件的.

// on request
$rootScope.$emit(_START_REQUEST_);

// on any response
$rootScope.$emit(_END_REQUEST_);
Run Code Online (Sandbox Code Playgroud)

我试图通过简单地使它们成为常量来"模块化"这些请求和响应事件.

.constant('_START_REQUEST_', '_START_REQUEST_');
Run Code Online (Sandbox Code Playgroud)

我试图找到一个解决方案,以"模块化"我的所有其他事件,如在项目的CRUD操作上发出的事件.我有一个想法是定义items工厂内的所有项目CRUD事件:

events: {
    update: 'itemUpdate',
    create: 'itemCreated'
    // etc.
}
Run Code Online (Sandbox Code Playgroud)

然后,我可以简单地将我的items工厂注入控制器,并像这样引用事件:

$rootScope.$on(items.events.update, function() {});
Run Code Online (Sandbox Code Playgroud)

我还考虑过简单地定义所有事件,无论它们是拦截器事件还是项目事件,都是我应用程序中的常量.然而,似乎这个解决方案直接将项目事件耦合到模块本身,而不是items工厂,这是我觉得它们"属于"的地方.

基本上,问题是现在所有的事件定义似乎都散布在各地.我的问题是:您建议在AngularJS中模块化和定义事件的模式或最佳实践什么?

adr*_*sch 4

我同意这些项目事件应该属于事件源。您可以在项目工厂中实现观察者模式,隐藏对$rootScope事件侦听器的依赖。这样,事件键本身就是项目工厂的私有详细信息,并且通过为其调用专用函数来明确对事件的订阅。这种方法使您的代码比事件名称约定更独立$rootScope且更易于维护(考虑特定事件订阅方法的用法搜索与 的用法$rootScope.$emit / $on):

angular.module('events', [])

.service('items', ['$rootScope', function($rootScope) {
  var createdEventKey = 'item.created';
    
  return {
      create: function () {
          $rootScope.$emit(createdEventKey, {"name": "aItemName"});
      },
      
      onCreated: function(callback, scope) {
          var unsubscribeFunction = $rootScope.$on(createdEventKey, function(event, payload) {
              callback(payload);
          });
          
          // allow to unsubscribe automatically on scope destroy to prevent memory leaks 
          if (scope) {
            scope.$on("$destroy", unsubscribeFunction);
          }
          
          return unsubscribeFunction;
      }   
  }
}])

.controller('TestController', function($scope, items) {
    items.onCreated(function (item) {
        console.log("Created: " + item.name);
    }, $scope);
});
Run Code Online (Sandbox Code Playgroud)

完整示例: http: //jsfiddle.net/8LtyB/32/