Compartir a través de


Resumen del capítulo 18. MVVM

Nota:

Este libro se publicó en la primavera de 2016 y no se ha actualizado desde entonces. Gran parte del libro sigue siendo útil, pero algunos de los materiales están anticuados y algunos temas ya no son completamente correctos o completos.

Una de las mejores formas de diseñar una aplicación es separar la interfaz de usuario del código subyacente, que a veces se denomina lógica de negocios. Existen varias técnicas, pero la que se adapta a los entornos basados en XAML se conoce como Modelo-Vista-Modelo de vista o MVVM.

Interrelaciones de MVVM

Una aplicación MVVM tiene tres niveles:

  • Modelo proporciona datos subyacentes, a veces a través de archivos o accesos web.
  • Vista es la interfaz de usuario o la capa de presentación, normalmente implementada en XAML.
  • Modelo de vista conecta el Modelo y la Vista.

Modelo es independiente de Modelo de vista y Modelo de vista es independiente de Vista. Estas tres capas generalmente se conectan entre sí mediante los mecanismos siguientes:

Vista, Modelo de vista y Vista

En muchos programas más pequeños (e incluso más grandes), a menudo Modelo está ausente o su funcionalidad está integrada en Modelo de vista.

Modelos de vista y enlace de datos

Para interactuar con los enlaces de datos, un Modelo de vista debe ser capaz de informar a Vista del cambio de una propiedad en Modelo de vista. Para ello, Modelo de vista implementa la interfaz de INotifyPropertyChanged en el espacio de nombres de System.ComponentModel. Esto forma parte de .NET y no de Xamarin.Forms. (Por lo general, los Modelos de vista intentan mantener la independencia de la plataforma).

La interfaz INotifyPropertyChanged declara un evento único denominado PropertyChanged que indica la propiedad que ha cambiado.

Un reloj de Modelo de vista

DateTimeViewModel en la biblioteca Xamarin.FormsBook.Toolkit define una propiedad de tipo DateTime que cambia en función de un temporizador. La clase implementa INotifyPropertyChanged y activa el evento PropertyChanged cada vez que cambia la propiedad DateTime.

En el ejemplo MvvmClock se crea una instancia de este Modelo de vista y se usan enlaces de datos al Modelo de vista para mostrar la información de fecha y hora actualizada.

Propiedades interactivas en un Modelo de vista

Las propiedades de un Modelo de vista pueden ser más interactivas, como se muestra por la clase SimpleMultiplierViewModel, que forma parte del ejemplo SimpleMultiplier. Los enlaces de datos proporcionan los valores de multiplicando y multiplicador de dos elementos Slider y muestran el producto con Label. Sin embargo, puede realizar cambios extensivos en esta interfaz de usuario en XAML sin que se realicen cambios en el Modelo de vista ni en el archivo de código subyacente.

Un Modelo de vista de colores

ColorViewModel en la biblioteca Xamarin.FormsBook.Toolkit integra los modelos de color RGB y HSL. Esto se muestra en el ejemplo HslSliders:

Captura de pantalla triple de TK

Optimización del Modelo de vista

El código de los Modelos de vista se puede simplificar mediante la definición de un método OnPropertyChanged que use el atributo CallerMemberName, que obtiene automáticamente el nombre de la propiedad que realiza la llamada. La clase ViewModelBase de la biblioteca Xamarin.FormsBook.Toolkit lo hace y proporciona una clase base para ViewModels.

Interfaz de comandos

MVVM funciona con enlaces de datos, y los enlaces de datos funcionan con propiedades, por lo que MVVM parece ser deficiente cuando se trata de controlar un evento Clicked de Button o un evento Tapped de TapGestureRecognizer. Para permitir que los Modelos de vista controlen estos eventos, Xamarin.Forms admite la interfaz de comandos.

La interfaz de comandos se manifiesta en Button con dos propiedades públicas:

Para admitir la interfaz de comandos, un Modelo de vista debe definir una propiedad de tipo ICommand que sea entonces un enlace de datos a la propiedad Command de Button. La interfaz ICommand declara dos métodos y un evento:

Internamente, un Modelo de vista establece cada propiedad de tipo ICommand en una instancia de una clase que implementa la interfaz ICommand. A través del enlace de datos, Button llama inicialmente al método CanExecute y se deshabilita a sí mismo si el método devuelve false. También establece un controlador para el evento CanExecuteChanged y llama a CanExecute cada vez que se desencadena ese evento. Si Button está habilitado, llama al método Execute cada vez que se hace clic en Button.

Es posible que tenga algunos Modelos de vista que son anteriores a Xamarin.Forms, y que estos ya admitan la interfaz de comandos. En el caso de los nuevos Modelos de vista que se van a usar solo con Xamarin.Forms, Xamarin.Formsproporciona una clase Command y una clase Command<T> que implementa la interfaz ICommand. El tipo genérico es el tipo del argumento para los métodos Execute y CanExecute.

Ejecuciones de método simples

En el ejemplo PowersOfThree se muestra cómo usar la interfaz de comandos en un Modelo de vista. La clase de PowersViewModel define dos propiedades de tipo ICommand y también define dos propiedades privadas que se pasan al constructor Command más sencillo. El programa contiene enlaces de datos de este Modelo de vista a las propiedades Command de dos elementos Button.

Los elementos Button se pueden reemplazar fácilmente por objetos TapGestureRecognizer en XAML sin cambios de código.

Una calculadora, casi

En el ejemplo AddingMachine se usan los métodos Execute y CanExecute de ICommand. Usa una clase AdderViewModel en la biblioteca Xamarin.FormsBook.Toolkit. El Modelo de vista contiene seis propiedades de tipo ICommand. Se inicializan desde el constructor Command y el constructor Command de Command y el constructor Command<T> de Command<T>. Todas las claves numéricas del equipo que agrega están enlazadas a la propiedad que se inicializa con Command<T>, y un argumento string a Execute y CanExecute identifica la clave determinada.

Modelos de vista y el ciclo de vida de la aplicación

AdderViewModel utilizado en el ejemplo AddingMachine también define dos métodos denominados SaveState y RestoreState. Se llama a estos métodos desde la aplicación cuando entra en suspensión y cuando se inicia de nuevo.