12

I have to implement some standard notification UI with angular js. My approach is the following (simplified):

<div ng-controller="MainCtrl">
  <div>{{message}}</div>
  <div ng-controller="PageCtrl">
     <div ng-click="showMessage()"></div>
  </div>
</div>

And with the page controller being:

module.controller("PageCtrl", function($scope){
  counter = 1
  $scope.showMessage = function(){
    $scope.$parent.message = "new message #" + counter++;
  };
});

This works fine. But I really don't like the fact that I need to call $scope.$parent.

Because if I am in another nested controller, I will have $scope.$parent.$parent, and this becomes quickly a nightmare to understand.

Is there another way to create this kind of global UI notification with angular?

1
  • 3
    try creating a service that would hold your messages, and inject the service to both controllers. just google for 'communicating controllers angularjs' it will show tons of links. Commented Jun 18, 2013 at 15:55

5 Answers 5

17

Use events to send messages from one component to another. That way the components don't need to be related at all.

Send an event from one component:

app.controller('DivCtrl', function($scope, $rootScope) {
  $scope.doSend = function(){
    $rootScope.$broadcast('divButton:clicked', 'hello world via event');
  }
});

and create a listener anywhere you like, e.g. in another component:

app.controller('MainCtrl', function($scope, $rootScope) {
  $scope.$on('divButton:clicked', function(event, message){
    alert(message);
  })
});

I've created a working example for you at http://plnkr.co/edit/ywnwWXQtkKOCYNeMf0FJ?p=preview

You can also check the AngularJS docs about scopes to read more about the actual syntax.

This provides you with a clean and fast solution in just a few lines of code.

Regards, Jurgen

Sign up to request clarification or add additional context in comments.

Comments

7

You should check this: An AngularJS component for easily creating notifications. Can also use HTML5 notifications. https://github.com/phxdatasec/angular-notifications

1 Comment

That project seems to be abandoned. Someone else has taken over maintenance and merged several PRs at: github.com/phxdatasec/angular-notifications. See announcement at: github.com/DerekRies/angular-notifications/issues/13
3

After looking at this: What's the correct way to communicate between controllers in AngularJS? and then that: https://gist.github.com/floatingmonkey/3384419

I decided to use pubsub, here is my implementation:

Coffeescript:

module.factory "PubSub", ->
  cache = {}
  subscribe = (topic, callback) ->
    cache[topic] = [] unless cache[topic]
    cache[topic].push callback
    [ topic, callback ]
  unsubscribe = (topic, callback) ->
    if cache[topic]
      callbackCount = cache[topic].length
      while callbackCount--
        if cache[topic][callbackCount] is callback
          cache[topic].splice callbackCount, 1
    null
  publish = (topic) ->
    event = cache[topic]
    if event and event.length>0
      callbackCount = event.length
      while callbackCount--
        if event[callbackCount]
          res = event[callbackCount].apply {}, Array.prototype.slice.call(arguments, 1)
      # some pubsub enhancement: we can get notified when everything
      # has been published by registering to topic+"_done"
      publish topic+"_done"
      res

  subscribe: subscribe
  unsubscribe: unsubscribe
  publish: publish

Javascript:

module.factory("PubSub", function() {
  var cache, publish, subscribe, unsubscribe;
  cache = {};
  subscribe = function(topic, callback) {
    if (!cache[topic]) {
      cache[topic] = [];
    }
    cache[topic].push(callback);
    return [topic, callback];
  };
  unsubscribe = function(topic, callback) {
    var callbackCount;
    if (cache[topic]) {
      callbackCount = cache[topic].length;
      while (callbackCount--) {
        if (cache[topic][callbackCount] === callback) {
          cache[topic].splice(callbackCount, 1);
        }
      }
    }
    return null;
  };
  publish = function(topic) {
    var callbackCount, event, res;
    event = cache[topic];
    if (event && event.length > 0) {
      callbackCount = event.length;
      while (callbackCount--) {
        if (event[callbackCount]) {
          res = event[callbackCount].apply({}, Array.prototype.slice.call(arguments, 1));
        }
      }
      publish(topic + "_done");
      return res;
    }
  };
  return {
    subscribe: subscribe,
    unsubscribe: unsubscribe,
    publish: publish
  };
});

1 Comment

I've been using pubsub to communicate between controllers and it has been working quite well.
1

My suggestion is don't create a one on your own. Use existing models like toastr or something like below. http://beletsky.net/ng-notifications-bar/

Comments

0

As suggested above, try to use external notifications library. There're a big variety of them:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.