Уведомления в пользовательском интерфейсе с помощью angular js

Мне нужно реализовать стандартный пользовательский интерфейс уведомлений с angular js. Мой подход следующий (упрощенный):

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

И с контроллером страницы:

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

Это прекрасно работает. Но мне действительно не нравится тот факт, что мне нужно вызвать $scope. $Parent.

Потому что, если я нахожусь в другом вложенном контроллере, у меня будет $scope. $parent. $parent, и это становится быстро кошмаром, чтобы понять.

Есть ли другой способ создания такого глобального уведомления пользовательского интерфейса с помощью angular?

Ответ 1

Использовать события для отправки сообщений с одного компонента на другой. Таким образом, компоненты не должны быть связаны вообще.

Отправить событие из одного компонента:

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

и создайте прослушиватель в любом месте, например, в другом компоненте:

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

Я создал рабочий пример для вас в http://plnkr.co/edit/ywnwWXQtkKOCYNeMf0FJ?p=preview

Вы также можете проверить AngularJS docs о областях, чтобы узнать больше о фактическом синтаксисе.

Это дает вам чистое и быстрое решение всего в нескольких строках кода.

С уважением, Jurgen

Ответ 2

Вы должны проверить это: Компонент AngularJS для легкого создания уведомлений. Также можно использовать уведомления HTML5. https://github.com/phxdatasec/angular-notifications

Ответ 3

Посмотрев на это: Каков правильный способ связи между контроллерами в AngularJS?, а затем: https://gist.github.com/floatingmonkey/3384419

Я решил использовать pubsub, вот моя реализация:

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
  };
});

Ответ 4

Мое предложение - создать не один. Используйте существующие модели, такие как toastr или что-то вроде ниже. http://beletsky.net/ng-notifications-bar/