Domanda

Ho un'applicazione GWT MVP con attività e luoghi. Questo si ispira campione di Mauro Bertapelle (nel questa discussione ), a quanto pare sulla base di alcuni dei lavori Thomas Broyer 's.

Ecco il problema: ho LoginActivity effettuare una chiamata RPC, che per un login riuscito, restituisce un utente. Questo utente ha un ruolo (per esempio, amministratore, utente regolare, guest). Diversi punti di vista e attività, tra cui un NavigatorView, dipendono da questo ruolo per ciò che mostrano o fanno. Come faccio ad avere questo caso l'utente alle altre attività?

Non ho un ClientFactory; iniezione (Gin) è utilizzato per istanziare le viste nel ActivityProviders che forniscono i miei Attività / presentatori, e le ActivityProviders sono iniettati nel mio ActivityMapper. Quindi questo può ridurre ad una domanda Gin: Come faccio ad avere il riferimento per l'utente dove è necessario? Questo sembra essere simile a questa domanda SO sui riferimenti globali in MVP.

me un novizio Gin Si consideri, questo è il mio primo tentativo di usarlo. Sto indovinando c'è un "modo Gin" per rendere questo accada, ma non so Gin abbastanza bene per sapere il modo migliore per farlo (se Gin dovrebbe essere utilizzato a tutti).

Molto grazie.

Modifica 1: Nonostante i miei sforzi alla ricerca SO per una domanda simile, ho appena trovato questa domanda che è praticamente identica alla mia (è l'algoritmo di SO per la ricerca di 'link correlati' meglio che la ricerca?). Sto pensando che la risposta Gin da David è sulla strada giusta.

Non credo che una soluzione di EventBus è possibile. Sto seguendo le Google linee guida che comportano istanziazione di attività in ogni luogo il cambiamento, per cui un singolo evento di per sé non sarà sufficiente.

È stato utile?

Soluzione

Ho avuto i requisiti simili su un recente progetto.

Quando ricevo una risposta da login (o logout) RPC I inviare un AuthenticationEvent personalizzato su EventBus. Tutte le attività che sono interessate a questo ascolto per questo evento. AuthenticationEvent ha un riferimento all'oggetto appuser che è nullo se utente basta disconnesso. Appuser contiene tutti i dati necessari (privilegi, gruppi, ecc ..) in modo che le attività possano ispezionare e agire su di esso.

A proposito di riferimenti globali: si può avere una classe con metodi statici che fornisce i dati di cui avete bisogno. Questa classe contiene internamente riferimenti Singleton a casi necessari. Nel mio esempio ho metodo AppUtils.getCurrentUser statico (). Internamente contiene un riferimento a appuser e ascolta anche AuthenticationEvent di set / reset questo campo.

Come nota a margine: non si basano su lato client per imporre restrizioni di accesso - si dovrebbe separare le servlet RPC in due gruppi: pubblici e privati. Pubblico è accessibile da chiunque (questo è fondamentalmente login / logout RPC e qualche altra informazione pubblica RPC), mentre RPC privata richiede autenticazione dell'utente. le restrizioni di accesso possono essere impostati per percorso / servlet: http: // codice .google.com / appengine / docs / java / config / webxml.html # Security_and_Authentication

Aggiornamento:

  1. Come annotato, classe con metodi statici non è consigliabile in questa configurazione, perché non è sostituibile e questo impedisce test (che è il punto di utilizzare GIN).

  2. La soluzione è quello di iniettare una classe di utilità partecipazione globali (AppUtils) in attività che richiedono le variabili globali. AppUtils devono essere dichiarati nella configurazione Singleton GIN come un caso è sufficiente per l'intera applicazione.

  3. Per usare Provider o non è solo una domanda se si desidera ritardare l'inizializzazione delle dipendenze (AppUtil è dipendenza). Dal momento che AppUtils è un Singleton per l'intera applicazione non ha senso di averlo pigro inizializzato.

  4. A volte si avrà una situazione in cui si dispone di più attività indicati sullo schermo (nel mio caso è stato Barra dei menu e barra informazioni). In questo caso, quando utente si collega sarà necessario un modo per comunicare il cambiamento. Usa EventBus.

Altri suggerimenti

Una cosa che sto usando sul lato server con Guice, e avrebbe funzionato altrettanto bene sul lato client, è quella di legarsi a un provider personalizzato. Nel tuo caso, però, che avrebbe dovuto imporre al prestatore un Singleton e spingere il valore in essa dal callback RPC (piuttosto che tirare da qualche contesto). Faresti prima bisogno di un provider specifico:

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

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

Si sarebbe legano User al provider: bind(User.class).toProvider(CurrentUserProvider.class) Nella tua callback RPC che ci si inietta un CurrentUserProvider in modo da poter setCurrentValue ma tutto il resto che ci si inietta Provider<User> per mantenere CurrentUserProvider come un dettaglio di implementazione. Per gli oggetti molto breve, si potrebbe direttamente iniettare un valore User piuttosto che un Provider<User>.

Se avete bisogno di comunicare gli oggetti del cambiamento di valore, si potrebbe inviare un evento sul bus evento globale.

In alternativa, si può sempre utilizzare il tipo concreto CurrentUserProvider (che non avrebbe dovuto implementare Provider più) ed eventualmente renderlo un HasValueChangeHandlers così si potrebbe registrare gli ascoltatori su di esso piuttosto che sull'autobus evento (ma dovreste clean-up dopo se stessi in onStop vostre attività e onCancel a perdite di memoria evitano, mentre è preso cura di automaticamente se si registra gestori sull'autobus evento onStart).

(se mi chiedete, preferirei andare via con l'autenticazione all'interno della app, quando possibile)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top