2017-01-03 2 views
1

Ich arbeite für eine Anwendung, und ich möchte Angular js mit einer Drittanbieter-js-Bibliothek kommunizieren. Dafür habe ich pubsub-Methode mit Mediator js verwendet. Aber deswegen, wenn ich ein Event abonniere, abonniere es mehrere Male und aufgrund dessen, wenn ich ein Event veröffentliche, wird es mehrmals ausgelöst. Um zu testen, diese Plunker PlunkrAngular js abonnieren mehrere Male und feuern mehrere Ereignisse

:

  1. Run Plunker

    für eine bessere Erklärung
    angular.module('app') 
        .service('mediator', function() { 
        var mediator = window.mediator || new Mediator(); 
        return mediator; 
    }); 
    
    // Main controller begins here 
        angular.module('app').controller('MainController', MainController); 
        MainController.$inject = ['mediator']; 
    
        function MainController(mediator){ 
        var vm = this; 
        vm.title = "This is main controller." 
    
        vm.sendMessage = function(){ 
         mediator.publish('something', { data: 'Some data' }); 
        } 
    
    
        } 
    
    
        // First page controller begins here 
        angular.module('app').controller('FirstController', FirstController); 
        FirstController.$inject = ['mediator']; 
    
        function FirstController(mediator){ 
        var vm = this; 
    
        console.log('Subscribed events for first controller.'); 
    
        var counter = 0; 
        mediator.subscribe('something', function(data){ 
         console.log('Fired event for '+ counter.toString()); 
         counter = counter + 1; 
        }); 
    
        } 
    

    Hier ist die Plunker:

    I unten Code verwendet haben.

  2. Öffnen Sie die Entwicklerkonsole.
  3. Klicken Sie auf Erste Seite
  4. Click Brandereignis
  5. Klicken Sie auf der zweiten Seite
  6. Klicken Sie auf der ersten Seite
  7. Klicken Sie auf Brandereignis

Wie Sie zur ersten Seite zweiten Mal navigieren, es wird das Ereignis erneut abonnieren und zweimal feuern. Dies wird mehrere Male abonnieren, wenn Sie mehrmals auf die erste Seite navigieren.

Bitte lassen Sie mich wissen, wenn ich etwas falsch mache.

+0

Sie werden derzeit jedes Mal abonnieren, wenn der Controller geladen wird. Dies geschieht jedes Mal, wenn Sie auf die Seite navigieren. Dies scheint ein einfacher Fall von Tracking zu sein, wenn Sie abonniert sind oder nicht und ein 'if (! Subscribed) 'oder ähnliches verwenden. – Claies

+1

Nun, Sie werden nicht abbestellen, wenn Ihr Controller zerstört wird. Es wird also weiterhin abonniert. Sie haben nicht nur mehrere Konsolenprotokolle, sondern auch ein schönes Speicherleck. –

+0

@JBNizet: Können Sie uns wissen lassen, wie Sie Event mit Mediator js abmelden? –

Antwort

1

Sie könnten sich abmelden, wenn der Controller zerstört wird.

dies mit Mediator zu tun, müssen Sie zuerst Abonnement-Funktion speichern:

var sub = function(data){ 
    console.log('Fired event for '+ counter.toString()); 
    counter = counter + 1; 
} 
mediator.subscribe('something', sub); 

Dann können Sie die Winkel Ereignis aus den Meldungen abmelden verwenden, wenn der Controller entfernt wird:

$scope.$on("$destroy", function() { 
    mediator.remove("something", sub); 
}); 

Wenn Sie dieses Muster verwenden, sollten Sie die Momente berücksichtigen, zu denen ein Abonnement entfernt werden muss, und zwar nicht nur für die Duplizierung, sondern auch für Speicherlecks.

Vergessen Sie nicht, Sie müssen auch $ scope injizieren (auch wenn es nicht als Inhaber des Modells, ist es in Ordnung, es zu benutzen Ereignis-Listener für die Registrierung):

angular.module('app').controller('FirstController', FirstController); 
FirstController.$inject = ['mediator', '$scope']; 

Plunkr Beispiel: https://plnkr.co/edit/CgYLLSxGF2Fww5vBB7PB

Hoffe es hilft.

+0

Ich möchte $ scope nicht in meinem Code verwenden. Gibt es einen Ausweg mit View Model Object (VM)? –

+0

Warum nicht? Ich bin mir nicht sicher, ob es eine direkte Möglichkeit gibt, Listener für VM-Ereignisse ohne $ scope zu registrieren, da es keine direkte Möglichkeit gibt, Modelländerungen ohne $ scope zu beobachten. Auch wenn Sie den Controller als empfohlenes Muster verwenden, gibt es immer noch einen Bereich, der von angular verwaltet wird. $ scope ist vollkommen in Ordnung für die oben genannten Dinge. –