在 AngularJS 中,Controller 之间可以共用的代码我们通常抽出来写成一个 Service。全局 Alert 消息系统就是一个很好的例子,比如“用户注册成功”、“添加商品成功”,每个 Controller 都有机会发出通告,这一部分功能应该写成独立模块。

Angular-UI Bootstrap 项目提供了一系列的模块,将 Bootstrap 中的 component 转换为原生的 Angular directives,如果你正在同时使用 Bootstrap 和 AngularJS,那么强烈建议你使用它。

angularui-alert

在 Angular-UI Bootstrap 的文档里,有下面的例子来创建一个 alert:

View:

<div ng-controller="AlertDemoCtrl">
  <alert ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">{{alert.msg}}</alert>
  <button class='btn' ng-click="addAlert()">Add Alert</button>
</div>

Controller:

function AlertDemoCtrl($scope) {
  $scope.alerts = [
    { type: 'error', msg: 'Oh snap! Change a few things up and try submitting again.' }, 
    { type: 'success', msg: 'Well done! You successfully read this important alert message.' }
  ];
 
  $scope.addAlert = function() {
    $scope.alerts.push({msg: "Another alert!"});
  };
 
  $scope.closeAlert = function(index) {
    $scope.alerts.splice(index, 1);
  };
}

假如说我们想要从很多不同的 Controller 发出 alert,那么像上面那样写就会导致跨 Controller 地调用函数,这属于 bad practice。我们将 alert 抽出来写成一个 Service ——

alertService:

'use strict';
/* services.js */
 
// 别忘记将本 service 依赖注入到你的 app
var appServices = angular.module('myApp.services', []);
 
appServices.factory('alertService', function($rootScope) {
    var alertService = {};
 
    // 创建一个全局的 alert 数组
    $rootScope.alerts = [];
 
    alertService.add = function(type, msg) {
      $rootScope.alerts.push({'type': type, 'msg': msg, 'close': function(){ alertService.closeAlert(this); }});
    };
 
    alertService.closeAlert = function(alert) {
      alertService.closeAlertIdx($rootScope.alerts.indexOf(alert));
    };
 
    alertService.closeAlertIdx = function(index) {
      $rootScope.alerts.splice(index, 1);
    };
 
    return alertService;
});

下面这段 HTML 可以放到你的 index.html 模板里,或者 include 到所有的页面。
View:

<alert ng-repeat="alert in alerts" type="alert.type" close="alert.close()">
    <span data-ng-bind-html="alert.msg"></span>
</alert>

最后,创建一个全局的 alert 就只需要在你的任何 Controller 里面调用 alertService.add() 即可,非常方便。

var UserCtrl = ['$scope', 'alertService',
    function(    $scope,   alertService) {
        alertService.add('warning', '这是一个警告消息!');
        alertService.add('error', "这是一个出错消息!");
 
        $scope.editProfile = function() {
            //...do something
            alertService.add('success', '<h4>成功!</h4> 你的个人资料已经修改。');
        }
}];

查看 Demo