venerdì 7 ottobre 2011

MVVM in 5 minuti


Vuoi vedere Model-View-ViewModel (MVVM) senza tutti gli "aiutanti"? Forse si pensava che stessi scherzando nel mio articolo precedente, " MVVM fondamentali ". Ora, io amo aiutanti per cose come comandante, comportamenti, messaggistica e localizzatori. Ma tengo alla mia precedente affermazione che queste cose aiutano MVVM, che è tutto separazione, non fanno MVVM. Questa è una distinzione importante.
Devo ammettere che con tutte le conversazioni su come sviluppare con MVVM a volte è difficile separare ciò che è MVVM e quello che è solo un aiutante. Questa è una delle ragioni che sto scrivendo su questi argomenti. Penso che sia importante fare questa distinzione per primo. Una volta capito MVVM, si può decidere quali aiutanti che si desidera utilizzare. Altrimenti si può seguire il percorso MVVM solo per sentire come hai fatto saltare all'indietro con un idrante.


Quindi diamo un'occhiata a MVVM senza fronzoli. Questa applicazione di esempio sarà la Ciao
Mondo della nostra generazione: una applicazione Twitter che sarà simile l'immagine in Figura 1.
Figura 1. L'immagine creata dalla TimelineView.xaml di una applicazione Twitter costruito utilizzando il Model-View-ViewModel.
Modello
mio Twitter applicazione ha bisogno tweet di apparire nella linea temporale principale. Quindi la prima cosa che faccio è creare un modello chiamato Tweet. La classe Tweet eredita da una classe che chiamo osservabili-Object, che implementa semplicemente il INotifyPropertyChanged (INPC) interfaccia. INPC è una semplice interfaccia che implementa un PropertyChanged, che è ciò che un modello deve comunicare ai controlli di una visualizzazione che qualcosa su una proprietà è cambiato. Avrei potuto implementato l'interfaccia INPC direttamente sul modello ma non ho mai farlo nel "mondo reale", quindi perché preoccuparsi qui. Mi piace il ObservableObject classe di base perché semplifica questo processo.
Il resto del mio modello ha una serie di proprietà che ne descrivono il Tweet, come ad esempio UserName. Tutte le proprietà chiamare il metodo RaisePropertyChanged (che è sulla classe ObservableObject):
protetti const string UserNameProperty = 
"UserName";
stringa _userName privati;
stringa UserName pubblico
{
  get {_userName ritorno;}
  insieme
  {
    if (_userName! valore =)
    {
      _userName = valore;
      RaisePropertyChanged (UserNameProperty,           
        TitleProperty);
    }
  }
}
Il modello è una semplice rappresentazione dei dati. E 'diviso in propria classe perché io possa avere più di un Vista dove voglio per visualizzare le informazioni tweet. La separazione favorisce il riutilizzo di codice.
ViewModel
La classe ViewModel è costruito per una vista. Sì, può essere utilizzato da più di un Vista, ma cerchiamo di non andare fuori su quello che-se e altri scenari molto ancora. Per ora, supponiamo che abbiamo un ViewModel il cui compito è quello di esporre i punti dati e la logica di presentazione che ha bisogno un View specifico. La classe ha una proprietà TimelineViewModel Tweets, che è un osservabile-Collection <Tweet> che aggrega un insieme di istanze della classe del modello per la vista della mia applicazione di esempio.
Qual è il compito principale del mio ViewModel?
  1. Esporre i modelli necessari per la visualizzazione (i tweet o IsBusy, per esempio)
  2. Esporre la logica necessaria per la visualizzazione (RefreshTweets, per esempio)
  3. Gestire qualsiasi logica di presentazione
Il ViewModel eredita da osservabili-Object (che implementa INPC), così tutte le sue proprietà farà si che il View sapere quando cambiano. Questo esempio utilizza solo un singolo modello, ma in molti casi il ViewModel può aggregare classi modello multiplo, che potrebbe anche essere grafi di oggetti. Il ViewModel è costruito per gestire la personalizzazione della esposizione dei dati per la visualizzazione. Quello che voglio dire è che il ViewModel può aggregare una o più classi del modello e aggiungere altre proprietà che la visualizzazione può avere bisogno. Per esempio, il mio Vista potrebbe essere necessario legarsi a proprietà come IsBusy o LoggedInAsName, nessuno dei quali si trovano nel Tweet modello. Posso semplicemente aggiungere questi al ViewModel, se necessario.
Il ViewModel si occupa anche di logica di presentazione. Un semplice esempio di questo è il compito di fare la chiamata per andare a prendere gli ultimi tweet e il caricamento della proprietà tweet nel ViewModel. Nella mia applicazione di esempio ho preso in giro questo quindi non è in realtà colpire i servizi di Twitter, ma il concetto è esattamente lo stesso.
OK, veloce punta pro: mi piacciono le mie classi ViewModel per dirigere le chiamate manipolazione dei dati, tuttavia, mi astratto le chiamate a un servizio dati, poi verso la propria classe. In questo esempio vorrei creare una classe chiamata TwitterService e sarebbe quindi apportare le chiamate API di Twitter. Il ViewModel sarebbe solo GetTweets chiamata al metodo della classe di TwitterService. Trovo questa astrazione veramente bello per tre grandi ragioni. In primo luogo, si nasconde l'API servizio Web le chiamate dal ViewModel, che in realtà può fregare di meno di come si ottiene i suoi dati.In secondo luogo, la classe TwitterService ora è riutilizzabile per classi ViewModel altri. Infine, questo è veramente grande per il design-time dei dati e per i dati beffe quando unit test.
Visualizza
Ora arriviamo alla View, il pezzo finale della triade MVVM. Il mio TimelineView ha una ListBox che definisce un ItemTemplate per visualizzare i tweets individuali. Timeline-View è databound al TimelineViewModel dichiarativo in XAML.In primo luogo, il ViewModel è creato come una risorsa statica:
<phone:PhoneApplicationPage.Resources>
  <local:TimelineViewModel x:Key="TimelineViewModel" />
</ Telefono: PhoneApplicationPage.Resources>
Poi la vista è associato ai dati del ViewModel impostando il DataContext. In applicazione di esempio faccio questo nel pannello esterno della pagina, che risulta essere la griglia:
DataContext = "{origine di associazione =
  StaticResource TimelineViewModel {}} "
Conclusioni
Quando si esegue l'applicazione di esempio vedrete non vi sono ulteriori riferimenti, nessun codice di magia, niente di niente, nada. Alcuni di voi starete chiedendo come collegare comunicazione l'interfaccia utente per il ViewModel, i comandi, comportamenti, localizzatori, iniezione di dipendenza, di inversione di contenitori di controllo, messaggi e dialoghi. Questi compiti possono certamente essere fatto con MVVM. In questa colonna si concentra sui fondamenti della MVVM. Naturalmente, ci sono ottimi modi per affrontare tutti questi scenari. Ma prima di volare, cerchiamo di camminare. E questo è prospettiva di papà.

Nessun commento:

Posta un commento