Question

J'ai une application GWT MVP en utilisant Activités et lieux. Ceci est inspiré par l'échantillon de Mauro Bertapelle (dans ce fil ), apparemment basé sur une partie du travail de ' Thomas Broyer .

Voici le problème: je LoginActivity faire un appel RPC, qui, pour une connexion réussie, renvoie un utilisateur. Cet utilisateur a un rôle (par exemple, admin, utilisateur régulier, invité). Plusieurs vues et activités, y compris un NavigatorView, dépendent de ce rôle pour ce qu'ils montrent ou faire. Comment puis-je obtenir cette instance de l'utilisateur aux autres activités?

Je n'ai pas ClientFactory; injection (Gin) est utilisé pour instancier les vues dans les ActivityProviders qui fournissent mes activités / présentateurs et les ActivityProviders sont injectés dans mon ActivityMapper. Donc, cela peut réduire à une question de Gin: comment puis-je obtenir la référence de l'utilisateur où il est nécessaire? Cela semble être similaire à cette question SO sur les références mondiales dans MVP.

Considérez-moi comme un débutant Gin, c'est ma première tentative de l'utiliser. Je devine que il y a un « chemin Gin » pour y arriver, mais je ne sais pas Gin assez bien pour connaître la meilleure façon de le faire (si Gin doit être utilisé du tout).

Une grande partie grâce.

Modifier 1: Malgré tous mes efforts à la recherche SO pour une question similaire, je viens de trouver cette question qui est à peu près identique à la mienne (est l'algorithme de SO pour trouver des liens "connexes" mieux que la recherche?). Je pense que la réponse Gin David est sur la bonne voie.

Je ne pense pas qu'une solution de EventBus est possible. Je suis les directives Google qui impliquent instanciation Activité à chaque endroit changement, donc un seul événement en lui-même ne suffira pas.

Était-ce utile?

La solution

J'ai eu des exigences similaires sur un récent projet.

Quand je reçois une réponse de connexion (ou déconnexion) RPC-je envoyer un AuthenticationEvent personnalisé sur EventBus. Toutes les activités qui sont intéressés à ce écouter cet événement. AuthenticationEvent a une référence à l'objet appuser qui est nul si l'utilisateur vient de se déconnecter. Appuser contient toutes les données nécessaires (privilèges, groupes, etc ..) afin que les activités puissent inspecter et agir.

A propos de références globales: vous pouvez avoir une classe avec des méthodes statiques fournissant des données que vous avez besoin. Cette classe contient des références en interne singleton aux instances nécessaires. Dans mon exemple, j'ai méthode AppUtils.getCurrentUser statique (). En interne, il contient une référence à appuser et écoute également AuthenticationEvent pour définir / réinitialiser ce champ.

Comme une note de côté: ne comptez pas sur le côté client pour faire respecter les restrictions d'accès - vous devez séparer vos RPC servlets en deux groupes: public et privé. Public est accessible par tout le monde (ce qui est fondamentalement connexion / déconnexion RPC et d'autres informations publiques RPC), tandis que RPC privé requiert que l'utilisateur doit être authentifié. Les restrictions d'accès peuvent être définies par chemin / servlet: http: // Code .google.com / appengine / docs / java / config / webxml.html # Security_and_Authentication

Mise à jour:

  1. Comme vous l'avez dit, la classe avec des méthodes statiques n'est pas conseillé dans cette configuration, car il n'est pas remplaçable, ce qui empêche l'essai (qui est le point de l'ensemble de l'utilisation GIN).

  2. La solution consiste à injecter un globals de maintien de classes d'utilité (les AppUtils) dans des activités qui ont besoin des variables globales. AppUtils doivent être déclarés singleton en configuration GIN comme une instance est suffisant pour l'application entière.

  3. Pour utiliser Provider ou non est une question si vous voulez retarder l'initialisation des dépendances (Apputil est la dépendance). Depuis AppUtils est un singleton pour l'application tout cela n'a aucun sens de l'avoir paresseux initialisé.

  4. Parfois, vous aurez une situation où vous avez plusieurs activités présentées à l'écran (dans mon cas, il était MenuBar et InfoBar). Dans ce cas, lorsque l'utilisateur se connecte, vous aurez besoin d'un moyen de les informer du changement. Utilisez EventBus.

Autres conseils

Quelque chose que j'utilise sur le côté serveur avec Guice, et travaillerait aussi bien sur le côté client, est de se lier à un fournisseur personnalisé. Dans votre cas, cependant, vous auriez à faire le fournisseur un singleton et pousser la valeur en elle depuis le rappel RPC (plutôt que le tirant d'un contexte). Vous auriez d'abord besoin d'un fournisseur spécifique:

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

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

Vous seriez lier User au fournisseur: bind(User.class).toProvider(CurrentUserProvider.class) Dans votre rappel RPC que vous souhaitez injectez un CurrentUserProvider afin que vous puissiez setCurrentValue mais partout ailleurs vous souhaitez injectez Provider<User> garder CurrentUserProvider comme un détail de mise en œuvre. Pour les objets de très courte durée, vous pourriez injecter directement une valeur User plutôt que d'un Provider<User>.

Si vous devez notifier des objets du changement de valeur, vous pouvez envoyer un événement sur le bus événement mondial.

Sinon, vous pouvez toujours utiliser le type de CurrentUserProvider de béton (qui ne pas avoir à mettre en œuvre Provider plus) et peut-être faire un HasValueChangeHandlers pour que vous puissiez enregistrer des écouteurs sur elle plutôt que sur le bus d'événements (mais vous auriez à nettoyage après vous dans le onStop de vos activités et onCancel pour éviter les fuites de mémoire, alors qu'il est pris en charge automatiquement si vous vous inscrivez des gestionnaires sur le bus d'événement dans onStart).

(si vous me demandez, je préfère aller loin avec l'authentification à partir de l'application lorsque cela est possible)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top