Frage

Ich habe eine GWT -MVP -Anwendung mit Aktivitäten und Orten. Dies ist inspiriert von Mauro Bertapelles Stichprobe (in Dieser Thread), anscheinend basierend auf einigen von Thomas BroyerArbeit.

Hier ist das Problem: Ich habe eine LoginActivity, die einen RPC -Aufruf tätigt, der für eine erfolgreiche Anmeldung einen Benutzer zurückgibt. Dieser Benutzer spielt eine Rolle (z. B. Administrator, regulärer Benutzer, Gast). Mehrere Ansichten und Aktivitäten, einschließlich eines Navigatorviews, hängen von dieser Rolle ab, was sie zeigen oder tun. Wie bekomme ich diese Benutzerinstanz für die anderen Aktivitäten?

Ich habe keine Kundenfaktorin; Die Injektion (GIN) wird zum Instanziieren der Ansichten in den Aktivitätspfleiern verwendet, die meine Aktivitäten/Moderatoren liefern, und die Aktivitätsanbieter werden in meinen Aktivitätsmapper injiziert. Dies kann also auf eine Gin -Frage reduzieren: Wie bekomme ich die Benutzerreferenz, wo sie benötigt wird? Dies scheint ähnlich zu sein wie Diese Frage Über globale Referenzen in MVP.

Betrachten Sie mich als Gin -Neuling, dies ist mein erster Versuch, es zu verwenden. Ich vermute, es gibt einen "Gin -Weg", um dies zu erreichen, aber ich kenne Gin nicht gut genug, um den besten Weg dazu zu wissen (wenn Gin überhaupt verwendet werden sollte).

Vielen Dank.

Bearbeiten 1: Trotz meiner besten Bemühungen für eine ähnliche Frage habe ich gerade festgestellt diese Frage Welches ist ziemlich identisch mit meiner (ist der SO -Algorithmus für das Finden von "verwandten" Links besser als die Suche?). Ich denke, dass die Gin -Antwort von David auf dem richtigen Weg ist.

Ich denke nicht, dass eine Eventbus -Lösung möglich ist. Ich folge dem Google -Richtlinien Dies beinhaltet die Instanziierung von Aktivitäten an jedem Ort, so dass ein einzelnes Ereignis selbst nicht ausreicht.

War es hilfreich?

Lösung

Ich hatte ähnliche Anforderungen an ein aktuelles Projekt.

Wenn ich eine Antwort von Login (oder Abmeldung) RPC erhalte, sende ich eine benutzerdefinierte Authentifizierung für EventBus. Alle Aktivitäten, die an diesem Hören für diese Veranstaltung interessiert sind. AuthenticationEvent hat einen Verweis auf Appuser -Objekt, das null ist, wenn der Benutzer gerade ausgeloggt wird. Appuser enthält alle erforderlichen Daten (Privilegien, Gruppen usw.), damit Aktivitäten sie überprüfen und darauf reagieren können.

Informationen zu globalen Referenzen: Sie können eine Klasse mit statischen Methoden haben, die Sie benötigen, die Sie benötigen. Diese Klasse enthält interner Referenzen auf die benötigten Instanzen. In meinem Beispiel habe ich statische Methoden apputils.getCurrentuser (). Intern wird ein Verweis auf Appuser und hört sich auch auf AuthenticationEvent auf, um dieses Feld festzulegen/zurückzusetzen.

Randnotiz: Verlassen Sie sich nicht auf die Kundenseite, um Zugriffsbeschränkungen durchzusetzen. Sie sollten Ihre RPC -Servlets in zwei Gruppen trennen: öffentlich und privat. Öffentlich kann von jedem zugegriffen werden (dies ist im Grunde genommen Login/Logout -RPC und einige andere öffentliche Info -RPC), während private RPC die Authentifizierung verlangt. Zugriffsbeschränkungen können pro Pfad/Servlet festgelegt werden: http://code.google.com/appengine/docs/java/config/webxml.html#security_and_authentication

Aktualisieren:

  1. Wie Sie bemerkt haben, ist die Klasse mit statischen Methoden in diesem Setup nicht ratsam, da sie nicht austauschbar ist und dies die Tests verhindert (was der springende Punkt der Verwendung von GIN ist).

  2. Die Lösung besteht darin, eine Versorgungsklasse mit Globals (Apputils) in Aktivitäten zu injizieren, die die Globalen benötigen. Apputils sollten in der GIN -Konfiguration als Singleton deklariert werden, da eine Instanz für die gesamte App ausreicht.

  3. Benutzen Provider Oder ist nur eine Frage, wenn Sie die Initialisierung von Abhängigkeiten verzögern möchten (Apputil ist Abhängigkeit). Da Apputils ein Singleton für die gesamte App ist, macht es keinen Sinn, sie faul initialisiert zu haben.

  4. Manchmal haben Sie eine Situation, in der Sie mehrere Aktivitäten auf dem Bildschirm angezeigt haben (in meinem Fall war es Menubar und Infobar). In diesem Fall benötigen Sie eine Möglichkeit, sie über die Änderung zu informieren. Verwenden Sie EventBus.

Andere Tipps

Etwas, das ich auf der serverseitigen Seite mit Guice verwende und auf der client-Seite genauso gut funktionieren würde, ist, an einen benutzerdefinierten Anbieter zu binden. In Ihrem Fall müssten Sie den Anbieter jedoch zu einem Singleton machen und den Wert aus Ihrem RPC -Rückruf in ihn drücken (anstatt ihn aus einem Kontext zu ziehen). Sie würden zuerst einen bestimmten Anbieter benötigen:

@Singleton
public class CurrentUserProvider implements Provider<User> {
  private User currentUser;

  public User get() { return currentUser; }
  public void setCurrentValue(User currentUser) {
    this.currentUser = currentUser;
  }
}

Du würdest Binden User an den Anbieter: bind(User.class).toProvider(CurrentUserProvider.class)In Ihrem RPC -Rückruf würden Sie a injizieren CurrentUserProvider also kannst du setCurrentValue Aber überall sonst würden Sie injizieren Provider<User> behalten CurrentUserProvider als Implementierungsdetail. Für sehr kurzlebige Objekte können Sie direkt a injizieren User Wert eher als a Provider<User>.

Wenn Sie Objekte über die Wertänderung informieren müssen, können Sie ein Ereignis im globalen Ereignisbus entsenden.

Alternativ können Sie immer den Beton verwenden CurrentUserProvider Typ (was nicht implementieren müsste Provider mehr) und möglicherweise zu einem HasValueChangeHandlers Sie könnten also Hörer als im Event-Bus registrieren (aber Sie müssten in Ihren Aktivitäten nach sich selbst aufräumen. ' onStop und onCancel Um Speicherlecks zu vermeiden, wird es automatisch gepflegt, wenn Sie Handler im Veranstaltungsbus in registrieren onStart).

(Wenn Sie mich fragen, würde ich lieber mit der Authentifizierung aus der App weggehen, wann immer möglich).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top