2012-05-18 23 views
11

Ho un ViewModel che contiene una squadra che ha una proprietà Players che è una lista di oggetti Player. All'interno di TeamView il Team è caricato a fondo, quindi i dati del giocatore sono già in memoria.Qual è il modo migliore per passare oggetti a "navigato a" viewmodel in MVVMCross?

Qual è il modo migliore per passare una determinata istanza della classe Player selezionata a PlayerView?

Il problema è che i costruttori di MVVMCross ViewModel possono contenere solo proprietà di stringa nella versione corrente.

ho le seguenti idee:

  1. passare l'ID del lettore selezionato e assegnare la proprietà Team.Players come ViewModel al PlayerView. Questa può essere una soluzione ragionevole se il giocatore selezionato è solo il giocatore focalizzato nel PlayerView e il PlayerView è in realtà una vista "giocatori", in cui l'utente può passare tra gli altri giocatori della squadra.

  2. Avere un servizio ASP.Net MVC come ViewBag che può trasportare dati solo tra azioni di navigazione, in un dizionario come memoria, e il parametro passato a PlayerView è un "viewbag: PlayerId123" che è una chiave speciale che punta al istanza di classe.

  3. Serializzare l'oggetto selezionato in stringa e passarlo come oggetto serializzato al costruttore. È possibile ma non mi piace questa soluzione.

risposta

13

Nella navigazione generale, MvvmCross consente solo il passaggio di stringhe tra ViewModels.

La ragione di ciò è che la navigazione deve essere eseguita a livello di piattaforma tramite meccanismi come Xaml Uris o Android Intents.

Per la situazione si suggeriscono, lo schema generale avrei typcially usare è:

  • che il TeamViewModel riceve i dati della squadra dal rete utilizzando un iniettato ITeamService
  • che il TeamViewModel utilizza anche un Singleton iniettato ITeamCache alla cache il team
  • che la navigazione avviene tramite una chiamata del tipo:

this.RequestNavigate<PlayerViewModel>(new { teamId, playerId })

  • il PlayerViewModel poi riceve il teamid e playerid nel suo costruttore, e utilizza l'ITeamCache per raccogliere il giocatore giusto

Questo codice potrebbe essere simile:

public class TeamViewModel 
    : MvxViewModel 
    , IMvxServiceConsumer<ITeamCache> 
{ 
    public TeamViewModel(string teamId, string playerId) 
    { 
     var teamCache = this.GetService<ITeamCache>(); 
     Player = teamCache.GetPlayer(teamId, playerId); 
     if (Player == null) 
     { 
      // todo - handle this error somehow! 
     } 
    } 

    public Player Player { get; set; } 
} 

Si noti che il codice sopra test per verificare se Player è null. Questo perché c'è un problema con la tua assunzione "All'interno di TeamView il Team è caricato a fondo, quindi i dati del giocatore sono già in memoria."

Il problema è che in piattaforme come Android e WP7, il sistema operativo è libero di rimuovere l'applicazione dalla memoria e quindi riavviarla in un secondo momento.Questo è indicato come Tombstoning su WP7, ma sembra essere chiamato semplicemente Killed su Android.

In questi casi, il sistema operativo può riavviare l'applicazione in un secondo momento quando l'utente torna indietro. Questo riavvio andrà direttamente all'attività in cui si trovava l'utente e ricorderà lo stack posteriore: sarà quindi l'applicazione a reidratare correttamente tutti gli oggetti necessari in memoria.

Ecco alcune molto piccole immagini che spiegano questo ...

Android lifecycle from Xamarin docsenter image description here

Per ulteriori dettagli, vedere Xamarin e MSDN


per la tua squadra caso/Player, potrebbe essere in grado di affrontare la reidratazione di:

  • Implementazione di ITeamCache come oggetto con backup di file - ad es. potrebbe utilizzare un file JSON o un database SQLite come archivio permanente per i dati in memoria
  • Implementare una logica nel codice che rimanda i dati dalla rete quando necessario
  • Implementazione di una strategia di emergenza-navigazione-back-home in questi casi - poiché questi casi non accadono spesso in molte applicazioni sui moderni telefoni ricchi di risorse.
  • Basta che si infrangono - anche se questo non è consigliabile ...

Non è una sorpresa, che molte applicazioni non gestiscono rimozione definitiva molto bene ...


Nota - per piccoli oggetti , la tua opzione 3 (serializzazione) può funzionare bene - tuttavia, questo non ti aiuterà con la situazione in cui si verifica la reidratazione delle app e un utente torna indietro da PlayerViewModel a TeamViewModel.


Per ulteriori informazioni su alcuni dei recenti cambiamenti su Android ai cicli di vita all'interno MvvmCross, vedere http://slodge.blogspot.co.uk/2012/05/android-application-initialization-and.html

+1

Grazie per la risposta Stuart ha senso, siamo fortunati che abbiamo già un database SQLite lato client, in modo il riavvio dell'app è un gioco da ragazzi, solo ITeamCache dovrebbe supportarlo. Lo accetto volentieri come risposta :-) –

+1

Qualcosa come l'esempio della conferenza dovrebbe mostrarti il ​​genere di cose che faccio tipicamente https://github.com/slodge/MvvmCrossConference – Stuart

+0

Una spiegazione così ricca! Grazie. – Askolein

Problemi correlati