0

この質問は、半分実用的で半分概念的です。私は同様の質問への回答を見てきましたが、私はAngularJSにかなり慣れていないため、これを行うための最良の方法(さまざまな意見を見てきました)がわかりません(とにかく私にとって)、または本当に、それを行うために書く実際のコードです。そのため、自分のアプリケーションの詳細について質問しています。

ここには似たようなタイトルの質問がたくさんあることは承知していますが、読み続けることをお勧めします.

要するに、1 つのページにまとめるモデルがたくさんあるので、たくさんのコントローラーがあります。フロント エンドが要求 (つまり、ユーザー アクション) をバック エンド コントローラーのいずれかにディスパッチすると、フロント エンドは次のような応答を取得します。

{"success":false,"errors":[{"text":"これは PHP コントローラーから送信されたエラーです。","type":"critical"}]}

ただし、AngularJS を使用して、エラー ログのモデルとビューを作成したいと考えています (クライアント側にのみ存在する必要があります)。つまり、アプリケーション内の他のすべてのコントローラーは、エラー ログにイベントを追加するために、エラー ログ コントローラーにアクセスする必要があります。

共有サービス/ファクトリの作成やルートスコープへのブロードキャストなど、いくつかのオプションを認識していると思います。また、他のすべてのコントローラーを、エラーやアラートなどを処理するコントローラーの子にすることがまったく理にかなっているのかどうかも疑問に思っていますが、本能的には、それは私には間違っていると感じています。

それを行う最善の方法は何ですか(エラーを処理する同じコントローラーがアラートやその他のグローバルタイプのハウスキーピングなども処理する可能性があることに注意してください)、誰かがこのモデルに基づく実際のコードを手伝ってくれますか動作がどのように見えるかをモックアップしましたか?

これは 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;
    };
});

JSFiddle で動作させるには、JSONP を使用する必要がありました。すべてがサーバー上にあるため、実際のプログラムではそれを行いません。

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>
4

2 に答える 2

2

最良のアプローチは工場/サービスルートをたどることであることがすでにわかっているようです。ただし、必要はありませんbroadcast。必要に応じて挿入できる単一のインスタンスを作成するだけです。

以下は、その方法の簡単な例です: http://jsfiddle.net/Ww8sS/3/

于 2013-08-01T09:52:58.020 に答える
1

私にとっては、コントローラのスコープにバインドした後に変数を作成するファクトリを使用するよりも、メッセージング パラダイム (ブロードキャスト) を使用する方が理にかなっています。これは、コントローラとサービス/ファクトリが結合されているため、変数を変更できないためです。コントローラーがサービス/ファクトリー変数とのリンクを失うため、サービス/ファクトリーの。

たとえば、サービス/ファクトリでログの配列をクリアする新しいメソッドを作成して、現在の配列を空にするのではなく新しい配列を作成する場合、その変更はそのコントローラーのスコープに反映されません。これは、スコープの変数ポイントが古いログの配列へ。例を見てください: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', '');
    };
}]);

とにかく、両方のソリューションにはいくつかの利点と欠点があります。

于 2013-08-01T11:09:43.457 に答える