So überschreiben Sie die Implementierung von $ exceptionHandler

73

Es gibt einige zusätzliche Dinge, die wir tun möchten, wenn eine Javascript-Ausnahme ausgelöst wird.

Aus den Dokumenten $exceptionHandler:

Jede nicht erfasste Ausnahme in Winkelausdrücken wird an diesen Dienst delegiert. Die Standardimplementierung delegiert einfach an $ log.error, wodurch sie in der Browserkonsole protokolliert wird.

Die Tatsache, dass dort "Standardimplementierung" steht, lässt mich denken, dass es eine Möglichkeit gibt, unsere eigene Implementierung für den Service bereitzustellen und das zu tun, was wir wollen, wenn eine Ausnahme ausgelöst wird. Meine Frage ist, wie machst du das? Wie können wir alle Ausnahmen für diesen Service beibehalten und dann die Funktionen bereitstellen, die wir möchten?

dnc253
quelle
1
Bitte wählen Sie als Antwort auf diese Frage die Lösung '$ deploy.decorator'.
Wizulus

Antworten:

173

Eine weitere Option , die ich für diese gefunden habe , ist zu „verzieren“ , die $exceptionHandlerdurch die $ provide.decorator Funktion. Auf diese Weise erhalten Sie einen Verweis auf die ursprüngliche Implementierung, wenn Sie diese als Teil Ihrer benutzerdefinierten Implementierung verwenden möchten. Sie können also so etwas tun:

mod.config(function($provide) {
    $provide.decorator("$exceptionHandler", ['$delegate', function($delegate) {
        return function(exception, cause) {
            $delegate(exception, cause);
            alert(exception.message);
        };
    }]);
});

Es wird das tun, was der ursprüngliche Ausnahmebehandler tut, sowie benutzerdefinierte Funktionen.

Siehe diese aktualisierte Geige .

dnc253
quelle
2
+1 - dies ist der bessere Weg, um das Problem sicher zu lösen.
Roy Truelove
Verwendet dies, aber es scheint nicht richtig zu minimieren!
Roger Far
Funktioniert es mit der Verwendung der Array-Notation, wie Sie es in Ihrer Bearbeitung getan haben? Sie müssen dies hier genau wie überall tun, wo die Abhängigkeitsinjektion verwendet wird, um mit der Minimierung zu arbeiten.
dnc253
@ dnc253 Ja, ich habe die Bearbeitung erst angewendet, nachdem ich es herausgefunden habe.
Roger Far
1
Ich würde raten VORSICHT: Dies kann alle Ausnahmen in Ihren Karma-Unit-Tests verschlucken, die definitiv nicht passieren wollen.
Hugo der Hungrige
56

Sie können die $exceptionHandlerFunktionalität überschreiben, indem Sie einen Dienst mit demselben Namen erstellen:

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

mod.factory('$exceptionHandler', function () {
    return function (exception, cause) {
        alert(exception.message);
    };
});

Sehen Sie sich diese Geige für ein Beispiel an. Wenn Sie die Factory-Definition für $exceptionHandlerauskommentieren, wird der Fehler an der Konsole protokolliert, anstatt ihn zu benachrichtigen.

Hier ist ein Gruppenthread , der ein Beispiel für das Einfügen anderer Dienste wie die $httpVerwendung enthält $injector.

Hinweis: Wenn Sie die vorhandene Funktionalität des $exceptionHandler(oder eines anderen integrierten Dienstes) nicht überschreiben möchten, finden Sie in dieser Antwort Informationen zum Dekorieren eines Dienstes.

Gloopy
quelle
Im Grunde können Sie also jeden Dienst überschreiben und die letzte Definition gewinnt, oder?
dnc253
9
Ich bevorzuge die Lösung von @ dnc253 gegenüber dieser. Durch die Verwendung der "Dekorator" -Funktionalität können Sie das vorhandene Verhalten beibehalten UND anderen Dekorateuren ermöglichen, sich an der Aktion zu beteiligen. Dieser wird alles blockieren, was bereits vorhanden ist, einschließlich Ihres eigenen Codes, wenn Sie dies aus einem anderen Grund bereits an anderer Stelle getan haben.
Brian Genisio
2
Ich stimme vollkommen zu, dass der Dekorateur ein sauberer Weg ist, dies zu tun.
Gloopy
1
Obwohl Dekorateure besser zu sein scheinen, scheint dies eine großartige Lösung zu sein, wenn Sie eine Factory oder etwas anderes verwenden möchten, das zum Zeitpunkt von module.config nicht initialisiert wurde
Hoppe
1
Funktioniert dies, wenn Sie es in einem separaten, enthaltenen Modul konfigurieren, sofern es sich um die letzte Definition handelt?
Casey
-5

Sie können jeden Service / jede Factory überschreiben, sogar $ cookieStore. Wenn Sie ein vollwertiges, konfigurierbares Objekt wünschen, ist hier ein wirklich schönes Beispiel :

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

//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});


function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {

   helloWorld.sayHello(),
}
Bartek Skwira
quelle