Co je MVVM?
Aplikace .NET MAUI, které nepoužívají MVVM, mají obecně více kódu v souborech kódu. Soubory kódu v .NET MAUI se řídí tímto vzorem: {something}.xaml.cs. Většina kódu v souboru kódu obvykle řídí chování uživatelského rozhraní (UI). Chování uživatelského rozhraní může zahrnovat cokoli, co se v uživatelském rozhraní stane, například změna barvy nebo textu. A může obsahovat cokoli, co se stane kvůli uživatelskému rozhraní, včetně obslužných rutin kliknutí na tlačítko.
Jedním z problémů s tímto přístupem je, že je obtížné psát testy jednotek proti souborům kódu. Soubory kódu často předpokládají stav aplikace, který je vytvořen parsováním XAML nebo dokonce vytvořeným jinými stránkami. Tyto podmínky se obtížně zpracovávají v spouštěči testů jednotek, které nemusí běžet ani na mobilním zařízení, a to ani s uživatelským rozhraním. Testy jednotek jsou tedy zřídka schopny otestovat chování uživatelského rozhraní v těchto souborech.
Tady je ale užitečný model MVVM. Při správném použití model MVVM tyto problémy řeší přesunutím většiny logiky chování uživatelského rozhraní do tříd testovatelných jednotek, které se nazývají viewmodels. Model MVVM se nejčastěji používá s architekturami, které podporují datové vazby. Je to proto, že pomocí rozhraní .NET MAUI můžete vytvořit vazbu jednotlivých prvků uživatelského rozhraní a viewmodel
odstranit nebo téměř eliminovat kód v zobrazení nebo za kódem.
Jaké jsou části aplikace MVVM?
viewmodel
I když je to jedinečná část modelu MVVM, model také definuje část modelu a část zobrazení. Definice těchto částí jsou konzistentní s některými dalšími běžnými vzory, jako je Model-View-Controller (MVC).
Co je model?
V aplikaci MVVM se termínový model používá k označení obchodních dat a operací. Model se nezabíná do prezentace uživatele aplikace.
Užitečné pravidlo pro určení kódu, který patří do modelu, je, že by měl být přenosný na různých platformách. Z mobilní aplikace do webového rozhraní nebo dokonce z programu příkazového řádku pomocí stejného modelu ve všech instancích. Nesouvisí s tím, jak se informace zobrazují uživateli.
Když uvažujete o aplikaci personálního oddělení z našeho scénáře, model může obsahovat Employee
třídu a Department
třídu, která uchovává data a logiku těchto entit. Model může obsahovat také věci, jako je třída, která uchovává logiku EmployeeRepository
trvalosti. Některé jiné vzory návrhu softwaru by zvažovaly, jako jsou úložiště odděleně od modelu. V kontextu MVVM ale často označujeme jakoukoli obchodní logiku nebo obchodní data jako součást modelu.
Tady jsou dva příklady modelu v jazyce C#:
public class Employee
{
public int Id { get; }
public string Name { get; set; }
public Employee Supervisor { get; set; }
public DateTime HireDate { get; set; }
public void ClockIn() { ... }
}
public class EmployeeRepository
{
public IList<Employee> QueryEmployees() { ... }
...
}
Co je zobrazení?
Kód zobrazení řídí věci, které přímo pracují s uživatelem, například ovládací prvky, jako jsou tlačítka a pole pro zadávání, a také další čistě vizuální prvky, jako jsou motivy, styly a písma.
V .NET MAUI nemusíte psát žádný kód jazyka C#, abyste si vygenerovali zobrazení sami. Místo toho často definujete zobrazení pomocí souborů XAML. Samozřejmě existují situace, které volají pro vlastní uživatelský ovládací prvek, ve kterém vytvoříte vlastní zobrazení prostřednictvím kódu.
Co je to viewmodel
?
To nás přivádí zpátky viewmodel
na . Jedná se viewmodel
o zprostředkující mezi naší obchodní logikou (model) a našimi zobrazeními (ui).
Zamyslete se nad tím viewmodel
, co může pro aplikaci personálního oddělení dělat. Řekněme, že existuje zobrazení, které zobrazuje dostupnou dovolenou zaměstnance a chcete, aby se zůstatek na dovolené zobrazoval jako "2 týdny, 3 dny, 4 hodiny". Obchodní logika v modelu ale poskytuje stejnou hodnotu jako 13,5 dnů, desetinné číslo představující celkový počet dní v 8hodinové pracovní době. Objektový model může vypadat jako v následujícím seznamu:
Model –
Employee
třída, která zahrnuje metodu:public decimal GetVacationBalanceInDays() { //Some math that calculates current vacation balance ... }
ViewModel –
EmployeeViewModel
třída, která má vlastnost, jako je tato:public class EmployeeViewModel { private Employee _model; public string FormattedVacationBalance { get { decimal vacationBalance = _model.GetVacationBalanceInDays(); ... // Some logic to format and return the string as "X weeks, Y days, Z hours" } } }
Zobrazení – stránka XAML, která obsahuje jeden popisek a tlačítko zavřít Popisek má vazbu na
viewmodel
vlastnost ':<Label Text="{Binding FormattedVacationBalance}" />
Pak stačí
BindingContext
, aby stránka byla nastavena na instanciEmployeeViewModel
.
V tomto příkladu model obsahuje obchodní logiku. Tato logika není vázána na vizuální zobrazení nebo zařízení. Stejnou logiku můžete použít pro ruční zařízení nebo stolní počítač. Zobrazení nezná žádnou obchodní logiku. Ovládací prvky zobrazení, jako je popisek, vědí, jak získat text na obrazovce, ale nezáleží na tom, jestli se jedná o zůstatek na dovolené nebo náhodný řetězec. Zná viewmodel
trochu obou světů, takže může fungovat jako zprostředkovatel.
Zajímavé je, jak viewmodel
se dosahuje zprostředkujícími výsledky: Zpřístupňuje vlastnosti, se kterými může zobrazení vytvořit vazbu. Veřejné vlastnosti představují jediný způsob, viewmodel
jak poskytuje data. To nás přivádí k tomu, proč se nazývá .viewmodel
Model v MVVM představuje strukturu, data a logiku obchodních procesů, viewmodel
představuje strukturu, data a logiku, kterou zobrazení vyžaduje.
Jak zobrazení funguje s aplikací viewmodel
?
Když se podíváte na vztah, který viewmodel
má s modelem, jedná se o standardní relaci třídy a třídy. Má viewmodel
instanci modelu a zveřejňuje aspekty modelu pro zobrazení prostřednictvím vlastností. Jak ale zobrazení získá a nastaví vlastnosti na kartě viewmodel
? Když se viewmodel
změní, jak zobrazení aktualizuje ovládací prvky vizuálu novými hodnotami? Odpověď je datová vazba.
Vlastnosti viewmodel
jsou přečtené v době, kdy je objekt svázán se zobrazením. Vazba ale nemá žádný způsob, jak zjistit, jestli viewmodel
se vlastnosti po použití vazby v zobrazení změní. viewmodel
Při změně se nová hodnota automaticky nerozšíší prostřednictvím vazby do zobrazení. Chcete-li provést aktualizaci z viewmodel
zobrazení do zobrazení, viewmodel
je nutné implementovat System.ComponentModel.INotifyPropertyChanged
rozhraní.
Rozhraní INotifyPropertyChanged
deklaruje jednu událost s názvem PropertyChanged
. Přebírá jeden parametr, název vlastnosti, která změnila jeho hodnotu. Systém vazeb použitý v rozhraní .NET MAUI rozumí tomuto rozhraní a naslouchá této události. Když se vlastnost změní na viewmodel
událost a vyvolá událost, vazba upozorní cíl změny.
Zamyslete se nad tím, jak to funguje v aplikaci personálního oddělení s zaměstnancem viewmodel
. Obsahuje viewmodel
vlastnosti, které představují zaměstnance, například jméno zaměstnance. Implementuje viewmodel
INotifyPropertyChanged
rozhraní a když se Name
vlastnost změní, vyvolá PropertyChanged
událost takto:
using System.ComponentModel;
public class EmployeeViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private Employee _model;
public string Name
{
get {...}
set
{
_model.Name = value;
OnPropertyChanged(nameof(Name))
}
}
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Zobrazení, které popisuje podrobnosti zaměstnance, obsahuje ovládací prvek popisku, který je svázán s viewmodel
Name
vlastností:
<Label Text="{Binding Name}" />
Když se Name
vlastnost změní v viewmodel
, PropertyChanged
událost je vyvolána s názvem této vlastnosti. Vazba naslouchá události a pak upozorní popisek, že se Name
vlastnost změnila. Vlastnost popisku Text
se pak aktualizuje o nejnovější hodnotu.