如何使指令仅响应拦截器广播的特定事件?

时间:2014-06-14 15:54:59

标签: node.js angularjs

目前我有一个应用程序,允许用户创建“项目”,删除它们,将它们移动到不同的文件夹等。

我现在将它们松散地定义为“CRUD”操作。无论何时在客户端进行CRUD操作,项目的数据也会在服务器上更新。

我的应用$http中有一个.config拦截器,如果成功或错误,会广播一个事件_END_REQUEST_,该事件在我的应用中定义为.constant (每当有任何请求开始时,也会广播_START_REQUEST_个事件。)

我有一个垃圾桶图标,按下后会删除已检查的项目。当项目被删除时,我想向用户显示某种成功消息(但是当项目被删除时,,而不是当它被移动到其他文件夹或其他任何内容时)。 )

目前,我有一个加载图标的指示,_START_REQUEST_上的加载图标设置为display: block,而_END_REQUEST_上的加载图标设置为display: none。这适用于每个请求。我想要删除项目时的成功消息仅在删除项目时发生。

我正在使用Node.js,因此一个选项是发回一个json响应,其中包含已完成的请求类型。例如:

// server
user.save(function(err) {
    if(err) res.send(500);

    res.json({'type': 'itemDeleted'});
});

// client
interceptor = ['$q', '$injector', function ($q, $injector) {
    var rootScope;

    function success(response) {
        // get $http via $injector because of circular dependency problem
        $http = $http || $injector.get('$http');
        // don't send notification until all requests are complete
        if ($http.pendingRequests.length < 1) {
            // get $rootScope via $injector because of circular dependency problem
            rootScope = rootScope || $injector.get('$rootScope');

            // send a notification requests are complete
            //check if it's an item (it will have a text field in data)
            if(response.data.type === 'itemDeleted') {
                rootScope.$broadcast(_ITEM_DELETED_);   
            }

            rootScope.$broadcast(_END_REQUEST_);
        }
        return response;
    }

然而,这个解决方案看起来有点不那么优雅了。如果我缩放它(比如说,我发回一种'itemSaved'或'itemMoved'),我可能会广播很多很多我必须跟踪的事件。有没有办法只播放一个事件(_END_REQUEST_)并仍然做我想做的事情?

1 个答案:

答案 0 :(得分:1)

不是使用其他事件区分响应,而是传递识别标志以及需要由收听者识别的任何广播。

在拦截器内部,它可能看起来像这样:

'response': function(response) {
    var flag;
    if (response.data.type === 'itemDeleted') flag = 'deleted';
    $rootScope.$broadcast('_END_REQUEST_', flag);
    return response;
},

然后,您可以在任何$on侦听器中检查此特定标志。例如:

directive('deleted', function($timeout) {
  return {
    restrict: 'E',
    link: function(scope, elem, attrs) {   
      scope.$on('_END_REQUEST_', function(event, flag) {
        if (flag === 'deleted') {
          scope.showDeleted = true;
          $timeout(function(){ scope.showDeleted = false }, 2000)
        } 
      })
    },
    template: '<div ng-show="showDeleted">Deleted</div>'
  }
})

Demo