0

I have two controller where both of them are listening to a same event. The event is sent from custom directive. Custom directive is reused in 2 other templates which belong to the controllers. And those 2 controllers are doing different actions when they catch the event. One is deleting the item from database, the other is simply deleting the item from collection on the view.

The controllers are called based on route. They are called from different route.

Now the problem is they both are catching the event at the same time. Is there any way to make them catch the event based on the route?

Or can you give me any explanation why the both controllers are being active even though supposedly only one should be being called based on the route?

angular.module('item.module')
    .directive('item', function($rootScope) {
        restrict: 'E',
        template: '<button ng-click="removeItem()"></button>'
        controller: function(){
            $scope.removeItem = function() {
                $rootScope.$emit('deleteThisItem', {item: $scope.item});
            };                  
        }
     };
);

function firstCtrl($scope, $rootScope)
{
    $rootScope.$on('deleteThisItem', function(event, data){
        //deletes the item from list from view
    });
}

function secondCtrl($scope, $rootScope)
{
    $rootScope.$on('deleteThisItem', function(event, data){
        //deletes the item from database
    });
}
milanis
  • 55
  • 1
  • 8
  • Can you try to listen ($on) in the $scope instead of the $rootScope? I think that if you listen on the $rootScope even if the controller is removed the listener stil fires. – Alberto May 10 '16 at 10:04
  • Separate controllers each one in a file. Reference controller*.js files only on pages that are needed. – Bettimms May 10 '16 at 11:15
  • @Alberto since the controllers and the custom directive has different scope and directive didn't inherit scope from any of those controllers, emitting event to $scope is not going to help in my situation. I already tried it. I stopped using it because the event was fired multiple times. – milanis May 11 '16 at 12:20
  • @milanis [emit vs broadcast](http://stackoverflow.com/questions/26752030/rootscope-broadcast-vs-scope-emit) emit dispatches an event upwards, and broadcast dispatches de event downwards, if you do $rootScope.$emit it won't be notified to others. Have you tride using broadcast instead of emit? – Alberto May 12 '16 at 09:48
  • @Alberto, yes I tried with broadcast as well. I am using $rootScope, because it can be used as global service communication bus. [as suggested here](http://stackoverflow.com/questions/27356299/global-communication-in-angular-module-event-bus-or-mediator-pattern-service#comment48122411_27481857) – milanis May 12 '16 at 13:18

1 Answers1

1

Since I couldn't find any better solution yet, I've come up the solution to check the location path before proceeding with the event. So in each controller after it catches the event, it checks if the current path is matching with the controller's path and if it is the case, it proceeds with deleting the item according to its logic.

It is not very optimal solution, but it is working so far. I hope it may help someone who faces same situation.

//firstcontroller.js
$rootScope.$on('deleteThisItem', function(event, data){
    if(!$location.path().startsWith('/first')) {
       //if the route is not on the first controller's path
       return;
    }
    //deletes the item from list from view
});

//secondcontroller.js
$rootScope.$on('deleteThisItem', function(event, data){
    if(!$location.path().startsWith('/second')) {
       //if the route is not on the second controller's path
       return;
    }
    //deletes the item from database
});
milanis
  • 55
  • 1
  • 8