繁体   English   中英

我的错误日志-在AngularJS中的各个控制器之间共享其方法

[英]my error log - sharing its methods across controllers in AngularJS

这个问题大约一半是实际问题,一半是概念问题。 我已经看过对类似问题的回答,但是我对AngularJS还是很陌生,只是不确定(对于我而言)执行此操作的最佳方式(我已经看到了不同的看法),或者实际上,我会写出执行此操作的实际代码,这就是为什么我要问自己的应用程序细节的问题。

我知道这里有很多标题相似的问题,但我敦促您继续阅读。

简而言之,我有一堆控制器,因为我将很多模型整合到一个页面中。 当前端向我的任何后端控制器调度一个请求(即用户操作)时,前端将获得一个响应,该响应可能看起来像这样:

{“成功”:false,“错误”:[{“文本”:“这是从PHP控制器发送的错误。”,“类型”:“关键”}]}

但是,我想使用AngularJS创建模型并查看错误日志(它只存在于客户端)。 因此,换句话说,为了将事件添加到错误日志中,应用程序中的所有其他控制器都将需要访问错误日志控制器。

我想我知道一些选项,例如创建共享服务/工厂并广播到rootscope。 我还想知道,使所有其他控制器成为处理错误,警报等问题的控制器的子代是否有意义,尽管本能地认为这对我来说是错误的。

最好的方法是什么(记住,处理错误的同一个控制器也可能处理警报和其他全局类型的内务处理),并且有人会帮助我根据该模型提供实际的代码我嘲笑该行为是什么样的?

它在JSFiddle上: http : //jsfiddle.net/Ww8sS/2/

这是代码。 这里可能有很多事情并不是做某事的最佳方法,但是就目前而言,我只关心我所描述的问题。

JS:

var userInterfaceApp = angular.module('user-interface', ['userInterfaceFilters']);

userInterfaceApp.controller('AnotherController', ['$scope', '$http', function($scope, $http) {

    $scope.doSomething = function() {
        $http({method: "JSONP", url: "http://uatu.net/test.php?action=do_something&callback=JSON_CALLBACK"}).
        success(function(data) {
            if(!data.success) {
                alert("How do I get the errors in data.errors to my error log?");
            }
        })
        .error(function(data, status, headers, config) {
            alert("Failure");
        // called asynchronously if an error occurs
        // or server returns response with an error status.
        });
    }
}]);

userInterfaceApp.controller('ConsoleEventController', ['$scope', function($scope) {
    $scope.errorLog = [];
    $scope.errorSortOrder = "-timestamp";

    $scope.addToErrorLog = function(errorArray) {
        for (var i = 0; i < errorArray.length; i++) {
            $scope.errorLog.push({"text" : errorArray[i].text, "type" : errorArray[i].type, "timestamp" : new Date()});
        }
    }

    //Not a real method--just here for demonstration
    $scope.createErrorMessage = function() {
        $scope.addToErrorLog([{"text" : "This is a sample error.", "type" : "critical"}]);
    }
}]);

var userInterfaceFilters = angular.module("userInterfaceFilters", []);

userInterfaceFilters.filter("logTimestamp", function() {
    return function(logDate) {
        var hours = logDate.getHours();
        var minutes = (logDate.getMinutes() < 10) ? "0" + logDate.getMinutes() : logDate.getMinutes();
        var seconds = (logDate.getSeconds() < 10) ? "0" + logDate.getSeconds() : logDate.getSeconds();
        return hours + ':' + minutes + ":" + seconds;
    };
});

我必须使用JSONP使其在JSFiddle上工作。 我不会在我的实际程序中这样做,因为它们都将在我的服务器上。

HTML:

<div ng-app="user-interface">
    <div ng-controller="AnotherController">
    <input type="button" value="Do Something" ng-click="doSomething()">    
    </div>

    <div ng-controller="ConsoleEventController">
        <p><input type="button" value="Create Error Message" ng-click="createErrorMessage()"></p>
        <h1>Error Log</h1>
        <ul id="error-log">
            <li ng-repeat="error in errorLog | orderBy:errorSortOrder" class="error-{{error.type}}">&lt;{{error.timestamp|logTimestamp}}&gt; {{error.text}}</li>
        </ul>
    </div>
</div>

听起来您已经知道最好的方法是走工厂/服务路线。 不过,无需broadcast -它们只是创建一个实例,您可以在必要时注入该实例。

这是您如何做的一个简单示例: http : //jsfiddle.net/Ww8sS/3/

对我来说,使用消息传递范例(广播)而不是使用工厂创建绑定到控制器作用域之后的变量的工厂更有意义,因为它确实将控制器和服务/工厂耦合在一起,所以您永远无法更改变量服务/工厂的价格,因为您的控制器将丢失与服务/工厂变量的链接。

例如,如果您想在服务/工厂中创建一个新方法来清除日志数组,从而创建新数组而不是清空当前数组,则该更改将不会反映在该控制器的作用域中,因为作用域的变量点到旧日志的数组; 看一下示例: http : //jsfiddle.net/Ww8sS/6/

var userInterfaceApp = angular.module('user-interface', ['userInterfaceFilters']);

userInterfaceApp.factory('errorLogs', function () {
    return {
        logs: [],
        addToErrorLog: function (errorArray) {
            for (var i = 0; i < errorArray.length; i++) {
                this.logs.push({"text": errorArray[i].text, "type": errorArray[i].type, "timestamp": new Date()});
            }
        },
        clearLogs: function () {
            this.logs = [];
        }
    }
});

userInterfaceApp.controller('AnotherController',
    ['$scope', '$http', 'errorLogs', function ($scope, $http, errorLogs) {

        $scope.doSomething = function () {
            $http({method: "JSONP", url: "http://uatu.net/test.php?action=do_something&callback=JSON_CALLBACK"}).
                success(function (data) {
                    if (!data.success) {
                        errorLogs.addToErrorLog(data.errors);
                    }
                })
                .error(function (data, status, headers, config) {
                    alert("Failure");
                    // called asynchronously if an error occurs
                    // or server returns response with an error status.
                });
        }
    }]);

userInterfaceApp.controller('ConsoleEventController',
    ['$scope', 'errorLogs', function ($scope, errorLogs) {
        $scope.errorLog = errorLogs.logs;
        $scope.errorSortOrder = "-timestamp";

        //Not a real method--just here for demonstration
        $scope.createErrorMessage = function () {
            errorLogs.addToErrorLog([
                {"text": "This is a sample error.", "type": "critical"}
            ]);
        }

        $scope.clearLogs = function () {
            errorLogs.clearLogs();
        };

    }]);

var userInterfaceFilters = angular.module("userInterfaceFilters", []);

userInterfaceFilters.filter("logTimestamp", function () {
    return function (logDate) {
        var hours = logDate.getHours();
        var minutes = (logDate.getMinutes() < 10) ? "0" + logDate.getMinutes() : logDate.getMinutes();
        var seconds = (logDate.getSeconds() < 10) ? "0" + logDate.getSeconds() : logDate.getSeconds();
        return hours + ':' + minutes + ":" + seconds;
    };
});

如果使用消息传递范式,它将使控制器与服务解耦,此外,该服务是独立的,任何控制器都可以侦听其事件。 http://jsfiddle.net/Ww8sS/5/

    var userInterfaceApp = angular.module('user-interface', ['userInterfaceServices', 'userInterfaceFilters']);

    userInterfaceApp.controller('AnotherController', ['$scope', '$http', 'logger', function($scope, $http, logger) {

        $scope.doSomething = function() {
            $http({method: "JSONP", url: "http://uatu.net/test.php?action=do_something&callback=JSON_CALLBACK"}).
            success(function(data) {
                if(!data.success) {
                    logger.addToErrorLog(data.errors);
                    //alert("How do I get the errors in data.errors to my error log?");
                }
            })
            .error(function(data, status, headers, config) {
                alert("Failure");
            // called asynchronously if an error occurs
            // or server returns response with an error status.
            });

        }

         $scope.clearLog = function() {
          logger.clearLog();      
        }
    }]);

    userInterfaceApp.controller('ConsoleEventController', ['$scope', function($scope) {
        $scope.errorSortOrder = "-timestamp";
        $scope.errorLog;

        $scope.$on('logger.newErrors', function (evt, errArray) {  
             $scope.errorLog = errArray;
            });

        $scope.$on('logger.clearLog', function (evt) {  
             $scope.errorLog = [];
            });


        //Not a real method--just here for demonstration
        $scope.createErrorMessage = function() {
           // $scope.addToErrorLog([{"text" : "This is a sample error.", "type" : "critical"}]);
        }
    }]);

var userInterfaceFilters = angular.module("userInterfaceFilters", []);

userInterfaceFilters.filter("logTimestamp", function() {
    return function(logDate) {
        var hours = logDate.getHours();
        var minutes = (logDate.getMinutes() < 10) ? "0" + logDate.getMinutes() : logDate.getMinutes();
        var seconds = (logDate.getSeconds() < 10) ? "0" + logDate.getSeconds() : logDate.getSeconds();
        return hours + ':' + minutes + ":" + seconds;
    };
});


var userInterfaceServices = angular.module('userInterfaceServices', []);

userInterfaceServices.service('logger', ['$rootScope', function ($rootScope) {

        var errorLog = [];

        this.addToErrorLog = function(errorArray) {
            for (var i = 0; i < errorArray.length; i++) {
                errorLog.push({"text" : errorArray[i].text, "type" : errorArray[i].type, "timestamp" : new Date()});
            }

            $rootScope.$broadcast('logger.newErrors', errorLog);
        };

    this.clearLog = function () {
      errorLog = [];
        $rootScope.$broadcast('logger.clearLog', '');
    };
}]);

无论如何,两种解决方案都有其优点和缺点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM