Reputation: 3435
I have a directive for flashmessages
'use strict';
angular.module('diplomovaPraceFrontendApp')
.directive('flashMessages', () ->
directive:
restrict: 'E'
replace: true
template: '<div ng-repeat="m in messages" id="flash-messages">' +
'<div class="alert {{m.level}}">' +
'<span class="">{{m.text}}</span>' +
'</div>' +
'</div>'
controller: ($scope, $rootScope) ->
$rootScope.$on('flash:message', (_, messages, done) ->
$scope.messages = messages
done()
)
)
and when I call in my controller $rootScope.$emit('flash:message', messages, someFunction); it isn't caught by $rootScope.$on() set up in directive, although if I put this in application.run() it works correctly.
Any ideas what I'm missing? Thanks for any advice
I have edited the question:
I do of course use an shared service, here's my code http://pastie.org/private/es25rvo0zvejuw9yx3acja (sorry, gist.github.com seems to be broken for me atm)
I was following this tutorial http://chiragchamoli.com/post/61277736964/building-a-flash-message-with-angular-js
Though it seems it doesn't call the directive at all, since replace is set to true and I still see <flash-messages>
in code inspector.
Plunkr version: http://plnkr.co/edit/buRaguEyTMuhUM9Z4Jsw?p=preview
Upvotes: 1
Views: 1071
Reputation: 194
I already gave a fix in #angularjs
earlier, but here it is for posterity:
http://plnkr.co/edit/Fb9FYSXgU0t93w7i2B8q?p=preview
The problem is that MainCtrl
is instantiated before the directive, so the $scope event gets fired before the directive sets a listener on $scope, so the directive never gets the event listened to here.
Upvotes: 1
Reputation: 1425
The problem is that your non directive controller function is called before the directive controller. Thus, the message is being sent before the the directive has registered for alerts.
A simple solution to this would be, instead of using events, use a shared service. Services are singletons, so any state is shared between all usages of that service. Using a service only makes sense if your all of your flashMessage directives need a shared state. If this solution does not fit your needs, help me better understand your requirements.
Working plunker
Javascript:
var app = angular.module('plunker', [])
.controller('MainCtrl', function ($scope, alertsService) {
alertsService.add({
text: 'I am an alert',
level: 'high'
});
})
.service('alertsService', function () {
this.alerts = [];
this.add = function (message) {
this.alerts.push(message);
}.bind(this);
})
.directive('flashMessages', function (alertsService) {
return {
restrict: 'E',
replace: true,
template: '<div ng-repeat="m in messages" id="flash-messages">' +
'<div class="alert {{m.level}}">' +
'<span class="">{{m.text}}</span>' +
'</div>' +
'</div>',
scope: true,
link: function ($scope) {
$scope.messages = alertsService.alerts;
}
};
});
HTML:
<body ng-controller="MainCtrl">
<flash-messages></flash-messages>
</body>
Upvotes: 0