2013-04-22 18 views
11

In MvvmCross v3 utilizzo ShowViewModel per spostarsi su pagine diverse. Prima di passare a Mvx, userei il metodo NavigationService.GoBack() per tornare alla pagina precedente. Il vantaggio è che la pagina non viene ricreata.Qual è il modo migliore per gestire GoBack per le diverse piattaforme MvvmCross (v3)

Poiché il metodo GoBack è una piattaforma specifica per WP, WInRT, Silverlight, qual è il modo migliore per gestire il ritorno alla pagina precedente in modo che il modello di visualizzazione rimanga indipendente dalla piattaforma?

Una soluzione potrebbe essere quella di utilizzare ShowViewModel passando alcuni dati che la vista può vedere e quindi nel caso di WP/WinRT, chiamando RemoveBackEntry dalla vista. Ma con Mvx, probabilmente c'è un modo migliore.

risposta

18

In MvvmCross v3, abbiamo fornito un meccanismo specifico per consentire a ViewModels di inviare messaggi all'interfaccia utente che vorrebbero modificare la presentazione corrente.

Questo meccanismo è ChangePresentation(MvxPresentationHint hint) e fornisce il routing dei messaggi - suggerimenti di presentazione - da ViewModels a Presenter.

Come il Presenter gestisce questi messaggi è specifico per la piattaforma e l'applicazione.

Questo meccanismo di messaggio è molto generale e potrebbe essere utilizzato per tutti i tipi di cose in futuro - ad es. gli sviluppatori potrebbero fornire suggerimenti che fanno cose come cambiare il layout dell'interfaccia utente, che evidenziano parte dell'interfaccia utente, che costringono l'utente a concentrarsi su un determinato controllo, che fa sì che il SIP venga visualizzato o nascosto, ecc.


Per il caso di chiusura di un modello di vista, abbiamo fornito una specializzazione delle MvxPresentationHint-MvxClosePresentationHint - ed un metodo di supporto in una classe base di MvxViewModel:

protected bool Close(IMvxViewModel viewModel) 
    { 
     return ChangePresentation(new MvxClosePresentationHint(viewModel)); 
    } 

Per utilizzare questa un ViewModel può basta chiamare Close(this)

Quando questo viene chiamato, il presentatore all'interno della vostra interfaccia utente riceverà un messaggio sul metodo ChangePresentation:

012.351.641.061.
public interface IMvxViewPresenter 
{ 
    void Show(MvxViewModelRequest request); 
    void ChangePresentation(MvxPresentationHint hint); 
} 

Per il caso generale/tipico - dove il ViewModel che viene chiuso è attaccato alla vista che è più in alto Activity/Page/UIViewController, presentatori predefinite all'interno MvvmCross saranno in grado di gestire questo messaggio e potranno a GoBack in Windows, a Finish in Android ea PopViewController in iOS.

Tuttavia, se l'interfaccia utente è più complicata di quella - ad es. se lo ViewModel corrisponde a Tab, a un Flyout, a un riquadro SplitView, ecc. o se lo ViewModel corrisponde a qualcosa di diverso dalla vista corrente più alta nella gerarchia, sarà necessario fornire un presentatore personalizzato implementazione - e che l'implementazione dovrà fare la logica specifica della piattaforma e dell'applicazione per gestire lo Close.


È possibile che questo suggerimento è quello che vi consiglio di utilizzare ...

Tuttavia, come alternativa :

Se si dovesse sentire questo meccanismo ChangePresentation(MvxPresentationHint hint) era semplicemente troppo pesante/eccessivo per la tua app, quindi puoi anche, naturalmente, scendere a un meccanismo basato su custom o Message.

Un campione che fa questo è il campione CustomerManagement - fornisce un'implementazione IViewModelCloser personalizzato su ogni piattaforma - vedi:

+0

Vedo e come hai detto tu potresti ereditare da un presentatore di piattaforme, ignorare ChangePresenter e dire a Mvx di usare il nuovo presentatore. –

3

Non sono completamente sicuro di mvvmcross, ma in MVVM Light ciò che viene solitamente fatto è creare un'interfaccia INavigationService che esponga questi metodi.

Quindi, ciascuna piattaforma implementa questa interfaccia nel modo specifico della piattaforma (in WP ad esempio ottenendo un riferimento al frame corrente e al suo contenuto). Questa istanza specifica della piattaforma può quindi eseguire tutte le azioni corrette per assicurarsi che il modello di navigazione sia correttamente implementato.

Il ViewModels può quindi ottenere un riferimento a un'istanza di INavigationService tramite un contenitore di dipendenze. In questo modo la tua VM è indipendente sulla piattaforma specifica della navigazione.

Ho anche scritto un post sul blog su come utilizzare interfacce per esporre un'API comune per le caratteristiche specifiche della piattaforma: http://www.kenneth-truyers.net/2013/02/24/patterns-for-sharing-code-in-windows-phone-and-windows-8-applications/

L'esempio nel post del blog è di circa isolato bagagli, ma gli stessi principi si applicano alla navigazione (o qualsiasi funzione che abbia implementazioni diverse su varie piattaforme)

+2

Ottimi punti, ma con Mvx tutti i modelli di visualizzazione per tutte le piattaforme vivono in una classe lib portatile. Quindi la navigazione è astratta con ShowViewModel in MvxNavigatingObject. E se per qualche ragione tutte le piattaforme non supportano qualcosa come GoBack, penso che non viva nel nucleo di Mvx. –

+0

OK, non lo sapevo. Come ho detto, non ho lavorato con MVVMcross, quindi forse i miei punti non sono validi nella tua situazione. Tuttavia, sarebbe una soluzione ereditare mvxNavigationObject e aggiungere quel metodo (astratto ovviamente)? È un'ipotesi selvaggia, forse non ha alcun senso. – Kenneth

+0

Hanno aggiunto una risposta - @ I punti generali di Kenneth sono chiari (quindi ho + 1ed).Tutta la mia risposta è di fornire le specifiche per come abbiamo fornito quell'astrazione all'interno di MvvmCross usando l'API 'ChangePresentation'. Oltre a fornire questa API, forniamo anche plugin mirati a cose come FileStorage :) – Stuart

Problemi correlati