2013-07-13 10 views
5

Ich benutze Winkel-js. Ich habe einen Dienst, der jedes Mal ein Ereignis auslösen muss, wenn etwas passiert. Dafür brauche ich ein Objekt, das als event aggregator fungiert.

  1. Muss ich einen bauen? Oder sollte ich die $rootScope verwenden?
  2. Falls ich $rootScope verwenden sollte, wie kann ich sicherstellen, dass es keine Konflikte bei Ereignisnamen gibt?
  3. Ist es effizient, $rootScope für Ereignisse zu verwenden, die sie nicht benötigen, um untergeordnete Bereiche zu propagieren?
+0

Was meinen Sie mit * Ereignis Aggregator *? Ist es der zentrale Punkt, um Ereignisse zu übertragen? Möchten Sie, dass alle Listener direkt an den * Ereignisaggregator * angehängt werden? – yuxhuang

+0

Ja. Ereignisaggregator ist ein zentrales Objekt, das Ereignisse und andere Objekte ausstrahlt. Zum Beispiel muss ein Dienst ein Ereignis "Aktion" senden, es wird vent.trigger ("Aktion") aufgerufen; und andere Objekte, die vent.on ('Aktion', Rückruf) ausgeführt haben; wird ihren Rückruf ausführen. – Naor

Antwort

13

I modelliert und implementiert den folgenden Mechanismus in einem Web-Projekt für Tabletten:

  1. D efine Benachrichtigungen in Ihren Diensten. Ich wollte nicht den Begriff Ereignisse verwenden, da ich nicht wollte, dass es mit DOM Ereignisse von anderen Entwicklern in meinem Team verwechselt werden. Und ein semi-typisierter Name für eine Benachrichtigung ist für IDE mit Intellisense-Unterstützung und zum Debuggen einfacher. Zum Beispiel habe ich einen Device Dienst, der $broadcast(Device.Notification.OrientationDidChange) würde, wenn die Ausrichtung eines Tablet-Geräts geändert wird.

  2. Verwenden Scope Objekte $broadcast oder $emitBenachrichtigungen, auf die je nach Bedarf. Zum Beispiel

    • für globale Benachrichtigungen wie die vorherigen, ich mache: $rootScope.$broadcast(Device.Notification.OrientationDidChange). So können alle Zuhörer auf ihren eigenen Bereich hören, ohne $rootScope zu injizieren.
    • Für lokale Benachrichtigungen, die möglicherweise nur den aktuellen Umfang beeinflussen könnten (und ihre Kinder), wie zum Beispiel eine Benachrichtigung, dass ein Rahmen alle Bereiche seines Kindes erzählen muss, dass das Layout der aktuellen Controller geändert wird, in der Regel I do: scope.$broadcast(UI.Notification.NeedsLayout), wobei ein vordefinierter Dienst für UI-bezogene Konstanten ist und scope der aktuelle Bereich ist.
    • Für bestimmte Benachrichtigungen, die ein Kind Umfang nach oben senden muss, beispielsweise ein Schieber-Direktive, die Aszendent Bereiche sagt, dass der rangeStart Wert (zusätzlich zu den regulären Zweiweg-Bindung) geändert hat, die ich benutze: scope.$emit(Slider.Notification.RangeStartDidChange), wo scope das ist aktueller Umfang.
  3. Dieser Ansatz ist in einem kleinen Projekt ein bisschen ausführlich. Vielleicht möchten Sie die ganze Zeit über $rootScope.$emit(Notification) verwenden und allen Zuhörern $rootScope.$on(Notification, callback) erlauben, diese Benachrichtigungen zu erhalten.

  4. In einigen Situationen möchten Sie diese Benachrichtigungen möglicherweise in einem zentralisierten Dienst definieren, um Namenskonflikte leichter zu vermeiden. Es basiert auf der Namenskonvention Ihres Projekts.

  5. Die Implementierung (tatsächliche Werte) dieser Benachrichtigungen kann variieren. Ich bevorzuge die Verwendung strings.

  6. Mit $broadcast oder $emit Sie können auch passieren tatsächlich zusätzliche Argumente an die Zuhörer zum Beispiel $broadcast(Notification, arg1, arg2) ... Angular's documentation recht detailliert.

4

Werfen Sie einen Blick auf http://docs.angularjs.org/api/ng.$rootScope.Scope#$broadcast.

  1. Mit $rootScope als Ereignis-Aggregator ist völlig in Ordnung, es sei denn, Sie sind auslösende Ereignisse outslide digest cycle oder Auslösen mehrere (100+) Ereignisse in der gleichen Zeit, wo einige andere Lösungen besser geeignet sein.
  2. Eine akzeptierte Praxis wäre Namespacing zu verwenden (namespace:event - Muster, die von Backbone.Marionette)
  3. Verwenden $emit auf ein Kind Umfang statt $broadcast auf $rootScope-$emit breitet sich nur nach oben, wo $broadcast nach unten ausbreitet - für alle Kinder
+0

Gute Antwort. Wichtiger Punkt: Bei $ rootScope werden $ broadcast und $ emot im Wesentlichen dasselbe tun. Da ist es die "Wurzel". –

+0

@blesh Ich denke nicht, dass das richtig ist, auf '$ rootScope' wird' $ emit' nur dort ausgelöst (da es keine Ebene mehr gibt), während '$ broadcast' in jedes' scope' hineinreicht Ihre App (die ein Performance-Killer ist). – yorch

+0

3. ist schlecht formuliert. Ich wollte sagen "used $ emit von einem Kind-Bereich statt $ Broadcast auf $ rootScope". Ich war nicht spezifisch genug. –

Verwandte Themen