AngularJS:如何与其他控制器共享作用域函数和变量

AngularJS: How to share scope functions and variables with other controllers

本文关键字:作用域 共享 函数 变量 控制器 其他 AngularJS      更新时间:2023-09-26

我的应用程序中有多个控制器,其中有一些重复的代码,如:

$scope.alert = null;
$scope.addAlert = function (message) {
    $scope.alert = { type: 'danger', msg: message };
};
$scope.clearAlerts = function () {
    $scope.alert = null;
};

在AngularJS中共享这些作用域函数和变量的推荐方式是什么?使用控制器继承?

创建一个控制器,然后在该控制器范围内放置通用方法。这样,您就可以在其他任何地方使用该作用域,并访问控制器内部的方法。

控制器

app.controller('commonCtrl', function($scope) {
    $scope.alert = null;
    $scope.addAlert = function(message) {
        $scope.alert = {
            type: 'danger',
            msg: message
        };
    };
    $scope.clearAlerts = function() {
        $scope.alert = null;
    };
});

然后,通过使用$controller注入该控制器来使用该控制器的作用域,然后在大括号内,您可以将公共控制器作用域分配给控制器的当前作用域。

通用控制器的使用

app.controller('testCtrl', function($scope, $controller) {
    //inject comomon controller scope to current scope , 
    //below line will add 'commonCtrl' scope to current scope
    $controller('commonCtrl', { $scope: $scope }); 
    //common controller scope will be available from here
});

或者更精确的方法是使用公共的可共享服务,该服务公开了两个方法和alert数据,您可以通过在控制器中注入服务名称来使用该服务方法。

服务

app.service('commonService', function($scope) {
    this.alert = null;
    this.addAlert = function(message) {
        this.alert = {
            type: 'danger',
            msg: message
        };
    };
    this.clearAlerts = function() {
        this.alert = null;
    };
});

控制器内部服务的利用

app.controller('testCtrl', function($scope, commonService) {
  console.log(commonService.alert);
  commonService.addAlert("Something");
  console.log("Updated Alert" + commonService.alert);
});

希望这能澄清你的想法,谢谢。

我自己针对这个用例的解决方案是定义一种类型的Observer Pattern。

代码的结构如下:

var app = angular.module('testModule', []);
app.factory('alertService', ['$timeout', function($timeout){
    var alertListeners = [];
    this.register = function (listener) {
        alertListeners.push(listener);
    };
    this.notifyAll = function (data) {
    for (// each listener in array) {
        var listenerObject = alertListeners[i];
        try { // do not allow exceptions in individual listeners to corrupt other listener processing
            listenerObject.notify(data);
        } catch(e) {
            console.log(e);
        }   
    }
    };
 }]).
 directive('myAlerts', ['alertService', function(alertService){
     var alertDirectiveObserver = function($scope, alertService) {
        this.notify = function(data) {
        /*
         * TO DO - use data to show alert
         */
         };
         /*
          * Register this object as an event Listener. Possibly supply an event key, and listener id to enable more resuse
          */
         alertService.register(this);
         $scope.on('$destroy', function() {
             alertService.unregister(// some listener id);
         });
     };

   return {
     restrict: 'A',
     template: '<div ng-class="alertClass" ng-show="alertNeeded">{{alertMessage}}</div>',
     controller: ['$scope', 'alertService', alertDirectiveObserver],
     link: function(scope){  
     }
    }
}]).
controller('alertShowingController', ['$scope', 'alertService',   function($scope, alertService){
    alertService.notifyAll({'warning', 'Warning alert!!!'})   
 ]);

alertShowingController是所有控制器如何简单地注入alertService并生成事件的简单示例。

我自己的实现更详细,因为它使用单独的事件键来允许控制器生成其他事件通知。

然后,我可以定义一个位于页面顶部固定位置的div,用于显示引导程序警报。

<div my-alerts ng-repeat="alert in alertList" type="{{alert.type}}" close="closeAlert(alertList, $index)">{{alert.msg}}</div>