2012-05-18 15 views
11

Tengo un ViewModel que contiene un equipo que tiene una propiedad de jugadores que es una lista de objetos de jugador. Dentro de TeamView, el equipo tiene una carga profunda, por lo que los datos del jugador ya están en la memoria.¿Cuál es la mejor forma de pasar objetos al modelo de vista "navegado a" en MVVMCross?

¿Cuál es la mejor manera de pasar una instancia de clase Jugador seleccionado dado a un PlayerView?

El problema es que los constructores MVVMCross ViewModel sólo pueden contener propiedades de cadena en la versión actual.

tengo las siguientes ideas:

  1. pase el ID del jugador seleccionado y asignar la propiedad Team.Players como un modelo de vista a la PlayerView. Esta puede ser una solución razonable si el jugador seleccionado es solo el jugador enfocado en PlayerView y el PlayerView es realmente una vista de "jugadores", donde el usuario también puede deslizar entre los otros jugadores del equipo.

  2. Tienen un ASP.Net MVC como el servicio ViewBag que puede transportar datos solo entre acciones de navegación, en un diccionario como almacenamiento, y el parámetro pasado a PlayerView es un "viewbag: PlayerId123" que es una tecla especial que apunta al instancia de clase.

  3. serializar el objeto seleccionado en cadena y pasarlo objeto como serializado al constructor. Es posible pero no me gusta esta solución.

Respuesta

13

En navegación general, MvvmCross solo permite pasar cadenas entre ViewModels.

La razón de esto es que la navegación que hay que hacer a un nivel de la plataforma a través de mecanismos tales como Xaml Uris o Intentos Android.

Para la situación que usted sugiere, el patrón general me gustaría utilizar typcially es:

  • que el TeamViewModel obtiene los datos del equipo de la red mediante un ITeamService inyectada
  • que el TeamViewModel también utiliza un producto único inyectada ITeamCache en caché el equipo
  • que la navegación pasa a través de una llamada como:

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

  • la PlayerViewModel recibe entonces el ID del equipo y playerId en su constructor, y utiliza el ITeamCache para recoger el jugador de la derecha

Este código podría ser:

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; } 
} 

en cuenta que el código las pruebas anteriores para si Player es null. Esto se debe a que hay un problema con su suposición: "Dentro de TeamView, el equipo tiene una carga profunda, por lo que los datos del jugador ya están en la memoria".

El problema es que en plataformas como Android y WP7, el sistema operativo es libre de retirar su solicitud de la memoria y a continuación, reiniciar más tarde.Esto se conoce como Tombstoning en WP7, pero parece que se llama Killed en Android.

En estos casos, entonces el sistema operativo puede reiniciar su aplicación más tarde cuando el usuario navegue de regreso. Este reinicio irá directamente a la actividad en la que estuvo el usuario por última vez, y recordará la pila de respaldo; luego estará en la aplicación rehidratar los objetos necesarios de nuevo a la memoria.

Éstos son algunos muy pequeños cuadros que explican esta ...

Android lifecycle from Xamarin docsenter image description here

Para más detalles, ver Xamarin y MSDN


para su caso/jugador de equipo, es posible que capaz de hacer frente a la rehidratación por:

  • Implementación de ITeamCache como un objeto respaldado por archivos, p. Ej. se podría utilizar un archivo JSON o una base de datos SQLite como un almacenamiento persistente para los datos de la memoria
  • ejecución cierta lógica en su código que refetches datos de la red cuando sea necesario
  • La aplicación de algunas navegar de vuelta a casa de emergencia-estrategia en estos casos, ya que estos casos no ocurren tan a menudo en muchas aplicaciones en teléfonos ricos en recursos modernos.
  • Sólo se estrellan - aunque esto no es recomendable ...

no es de extrañar, que muchas aplicaciones no manejan muy bien el cabeceo ...


Nota - para objetos pequeños , su opción 3 (serialización) puede funcionar bien; sin embargo, esto no lo ayudaría con la situación en la que ocurre la rehidratación de la aplicación y un usuario luego regresa de un PlayerViewModel a un TeamViewModel.


Para más información sobre algunos de los recientes cambios en Ciclo de Vida Android dentro MvvmCross, ver http://slodge.blogspot.co.uk/2012/05/android-application-initialization-and.html

+1

Gracias por la respuesta Stuart tiene sentido, tenemos suerte de que ya tenemos una base de datos SQLite lado del cliente, por lo el reinicio de la aplicación es obvio, solo ITeamCache debería ser compatible. Con mucho gusto lo acepto como una respuesta :-) –

+1

Algo así como la muestra de la conferencia debería mostrarle el tipo de cosas que normalmente hago https://github.com/slodge/MvvmCrossConference – Stuart

+0

¡Una explicación tan rica! Gracias. – Askolein

Cuestiones relacionadas