2

私は Angular 1.08 を使用しているため、使用する必要がありますresponseInterceptors

まずはコード。

通訳者:

app.factory('errorInterceptor', ['$q', 'NotificationService', function ($q, NotificationService) {
    return function (promise) {
        return promise.then(function (response) {
            // do something on success
            return response;
        }, function (response) {
            // do something on error
            alert('whoops.. error');
            NotificationService.setError("Error occured!");

            return $q.reject(response);
        });
    }
}]);

app.config(function ($httpProvider) {
    $httpProvider.responseInterceptors.push('errorInterceptor');
});

通知サービス:

app.service("NotificationService", function () {
    var error = '';

    this.setError = function (value) {
        error = value;
    }

    this.getError = function () {
        return error;
    }

    this.hasError = function () {
        return error.length > 0;
    }
});

ディレクティブ エラー ボックス:

app.directive("errorBox", function (NotificationService) {
    return {
        restrict: 'E',
        replace: true,
        template: '<div data-ng-show="hasError">{{ errorMessage }}</div>',
        link: function (scope) {
            scope.$watch(NotificationService.getError, function (newVal, oldVal) {
                if (newVal != oldVal) {
                    scope.errorMessage = newVal;
                    scope.hasError = NotificationService.hasError();
                }
            });

        }
    }
});

問題:<error-box>複数の場所で使用すると、これらすべてのボックスにエラー メッセージが表示されます。これは私の意図ではありません。例外が発生したエラーボックスのみを表示したいと思います。

たとえば、トランザクションのリストを表示するディレクティブがあります。トランザクションの取得に失敗した場合、その部分で宣言されているエラーボックスを表示したい。また、顧客を編集できるディレクティブもあります。このディレクティブには、エラー ボックス タグも含まれています。

顧客の保存に失敗すると、両方のエラー ボックスが表示されますが、顧客のエラー ボックスのみを表示したいのです。

誰かがこれを実装するアイデアを持っていますか?

4

1 に答える 1

3

Angular サービスは、こちらの角度ドキュメントで説明されているように、Singleton オブジェクトです。これは、Angular がサービスの単一の「グローバル」インスタンスのみを作成し、特定のサービスが要求されるたびにその同じインスタンスを使用することを意味します。つまり、Angular はサービスのインスタンスを 1 つだけ作成し、その 1 つのインスタンスをディレクティブNotificationServiceのすべてのインスタンスに提供します。errorBoxしたがって、1 つのディレクティブがNotificationServiceのエラー値を更新すると、すべての<error-boxディレクティブがその値を取得します。

そのため、エラーの種類ごとに複数の通知サービスを作成するか (や など)、特定のアラート (TransactionNotificationやなど)のみを設定できるようにCustomerNotificationするさまざまなメソッドをメインに追加する必要があります。NotificationServiceNotificationService.setCustomerError()NotificationService.setTransactionError()

これらのオプションはどれも特にユーザーフレンドリーでもクリーンでもありませんが、(サービスをセットアップした方法を考えると) それが唯一の方法だと思います。

更新:考えた後、NotificationServiceクラス全体を削除し、エラーが発生したときに$scopeイベントを使用して要素に通知することをお勧めします。<error-box>

あなたの'errorInterceptor'

app.factory('errorInterceptor', ['$q', '$rootScope', function ($q, $rootScope) {
    return function (promise) {
        return promise.then(function (response) {
            // do something on success
            return response;
        }, function (response) {
            // do something on error
            alert('whoops.. error');
            var errorType = ...; // do something to determine the type of error
            switch(errorType){
                case 'TransactionError':
                    $rootScope.$emit('transaction-error', 'An error occurred!');
                    break;
                case 'CustomerError':
                    $rootScope.$emit('customer-error', 'An error occurred!');
                    break;
                ...
            }

            return $q.reject(response);
        });
    }
}]);

そして、あなたのerrorBoxディレクティブで:

link: function (scope, element, attrs) {
        var typeOfError = attrs.errorType;
        scope.$on(typeOfError, function (newVal, oldVal) {
            if (newVal != oldVal) {
                scope.errorMessage = newVal;
            }
        });

    }

そして、あなたの見解では:

<error-box error-type="transaction-error"></error-box>
<error-box error-type="customer-error"></error-box>

それは理にかなっていますか?

于 2013-10-18T16:06:41.450 に答える