It's not possible to register an $emit or $broadcast event without $scope or $rootScope being injected in the controller.
It is indeed bad practice to use $scope variables and functions since the instance of your controller is already injected inside the $scope with the controllerAs syntax.
But there is not other choice than injecting scope objects if you want to use these events.
However you shouldn't use $emit or $broadcast events just to share data. These events are used for application wide information (like user has logged in or logged out...etc.)
A good practice when using angular events is to prefer $rootScope.$emit because $scope relies on the hierarchy of your components.
For example:
$scope.$emit will emit to the parent component.
$scope.$broadcast will broadcast to children components.
Then $rootScope.$broadcast will broadcast events to the rootScope as well as the scope (which may make your code messy real quick)
$rootScope.$emit is to be preferred as it registers the event application wide and makes it available to the rootScope only. ($rootScope.$on)
Another good practice is to unbind your custom events.
Whenever a component or directive is unloaded/destroyed, the event listener will still reside inside rootScope resulting in possible memory leaks.
To unbind an event:
var unbind = $rootScope.$on('logout', function(event, data) {
console.log('LOGOUT', data);
});
$scope.$on('$destroy', unbind);