Viste strongmente tipizzate, ViewModel e MVC

2

Sto imparando MVC e il libro che sto usando privilegia le visualizzazioni strongmente tipizzate. Alcuni di questi concetti sono nuovi per me e sto cercando di capire meglio la filosofia del design. Le visualizzazioni strongmente tipizzate comportano in genere la necessità di creare un ViewModel poiché è improbabile che le entità di dominio dispongano di tutte le informazioni di cui una determinata vista potrebbe avere bisogno. Il problema ora è che ho bisogno di aggiornare il mio ViewModel ogni volta che le entità di dominio associate o la vista cambia. Inoltre, non vedo che ViewModel sia molto utile quando si esegue il porting di un'applicazione su un'altra piattaforma, ad esempio da web a desktop o da web a mobile.

Non sarebbe meglio se potessimo dichiarare i nostri oggetti, collezioni, ecc. e popolarli nel controller e quindi essere in grado di accedere a queste variabili direttamente nella vista?

Il controller avrebbe un aspetto simile a:

    public ActionResult Index() {
        User user = db.Users.Where(u => u.UserId = userId);
        List<Car> carList = db.Cars.Where(c => c.OwnerId = userId).ToList();
        return View("UserCars");
    }

La vista sarebbe:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Title</title>
</head>
<body>
    <div id="username">
        @{user.UserName;}
    </div>
    <div id="carlist">
        @foreach (var car in carList) {
            car.Name
            <br />
        }
    </div>
</body>
</html>

Cosa c'è di sbagliato in questo approccio e cosa rende le viste strongmente tipizzate, e per estensione, ViewModels meglio?

Modifica: spiegazione vista strongmente tipizzata: link

Modifica: so che il codice non funzionerà, è lì per illustrare la mia domanda.

La mia preoccupazione è mantenere sincronizzati un modello, un modello di visualizzazione e una vista. Se la vista cambia, devo cambiare il viewmodel. Se cambio un bool in un bool nullable nel modello, devo cambiarlo in qualsiasi viewmodels che faccia riferimento a quel modello. Se ho un viewmodel separato per ogni vista e il mio sito web è abbastanza grande, ci sono molti posti da aggiornare. Non cambio le cose in un posto, le cambio in 50 posti o 100 posti. Ho pensato che le buone pratiche di programmazione tentassero di evitare questo tipo di problema.

    
posta Legion 18.12.2014 - 20:53
fonte

1 risposta

4

Preferisco anche le visualizzazioni strongmente tipizzate con ViewModels dedicati.

Per aggirare il problema che vedi, a volte costruisco i miei ViewModel come:

public class UserCarsViewModel
{
    public User User { get; set; }
    public List<Car> Cars { get; set; }

    public bool SomeCalculationIDontWantToHaveToDoInRazor
    {
        get { return _some mildly complex code here_ }
    }

    public List<Car> SomeFilteringIDontWantToHaveToDoInRazor
    {
        get { return _some mildly complex code here_ }
    }

    public bool SomeOtherConditionIDontWantToHaveToDoInRazor
    {
        get { return _some mildly complex code here_ }
    }
}

Tutta l'elaborazione più che mortale che altrimenti dovrebbe essere nel codice della vista (Razor) verrebbe inserita nel ViewModel, dove può essere più facilmente testata. Il codice Razor è, a sua volta, molto più facile da leggere.

Ma anche i miei modelli sono lì, pronti per essere usati così com'è. Se i Modelli cambiano, ma le modifiche non influiscono sui calcoli del ViewModel, i miei ViewModel non devono essere modificati.

Il mio controller ha l'aspetto di:

public ActionResult Index() 
{
    var viewModel = new UserCarsViewModel();
    viewModel.User = db.Users.Where(u => u.UserId = userId);
    viewModel.Cars = db.Cars.Where(c => c.OwnerId = userId).ToList();
    return View("UserCars", viewModel);
}
    
risposta data 19.12.2014 - 00:43
fonte

Leggi altre domande sui tag