Navigasi
Tip
Konten ini adalah kutipan dari eBook, Pola Aplikasi Perusahaan Menggunakan .NET MAUI, tersedia di .NET Docs atau sebagai PDF gratis yang dapat diunduh yang dapat dibaca secara offline.
.NET MAUI menyertakan dukungan untuk navigasi halaman, yang biasanya dihasilkan dari interaksi pengguna dengan UI atau dari aplikasi itu sendiri sebagai akibat dari perubahan status berbasis logika internal. Namun, navigasi dapat rumit untuk diterapkan di aplikasi yang menggunakan pola Model-View-ViewModel (MVVM), karena tantangan berikut harus dipenuhi:
- Mengidentifikasi tampilan yang akan dinavigasi untuk menggunakan pendekatan yang tidak memperkenalkan kopling dan dependensi yang ketat di antara tampilan.
- Mengoordinasikan proses di mana tampilan yang akan dinavigasi dibuat dan diinisialisasi. Saat menggunakan MVVM, tampilan dan model tampilan perlu dibuat dan dikaitkan satu sama lain melalui konteks pengikatan tampilan. Saat aplikasi menggunakan kontainer injeksi dependensi, instansiasi tampilan dan model tampilan mungkin memerlukan mekanisme konstruksi tertentu.
- Apakah akan melakukan navigasi view-first, atau navigasi view-model-first. Dengan navigasi tampilan-pertama, halaman untuk menavigasi untuk merujuk ke nama jenis tampilan. Selama navigasi, tampilan yang ditentukan dibuat, bersama dengan model tampilan yang sesuai dan layanan dependen lainnya. Pendekatan alternatif adalah menggunakan navigasi view-model-first, di mana halaman untuk menavigasi merujuk ke nama jenis model tampilan.
- Menentukan cara memisahkan perilaku navigasi aplikasi dengan bersih di seluruh tampilan dan model tampilan. Pola MVVM memisahkan UI aplikasi dan logika presentasi dan bisnisnya, tetapi tidak menyediakan mekanisme langsung untuk mengikatnya bersama-sama. Namun, perilaku navigasi aplikasi akan sering menjangkau UI dan bagian presentasi aplikasi. Pengguna akan sering memulai navigasi dari tampilan, dan tampilan akan diganti sebagai akibat dari navigasi. Namun, navigasi mungkin sering juga perlu dimulai atau dikoordinasikan dari dalam model tampilan.
- Menentukan cara meneruskan parameter selama navigasi untuk tujuan inisialisasi. Misalnya, jika pengguna menavigasi ke tampilan untuk memperbarui detail pesanan, data pesanan harus diteruskan ke tampilan sehingga dapat menampilkan data yang benar.
- Navigasi koordinasi untuk memastikan bahwa aturan bisnis tertentu dipatuhi. Misalnya, pengguna mungkin diminta sebelum menavigasi jauh dari tampilan sehingga mereka dapat memperbaiki data yang tidak valid atau diminta untuk mengirimkan atau membuang perubahan data apa pun yang dibuat dalam tampilan.
Bab ini membahas tantangan ini dengan menyajikan kelas layanan navigasi bernama MauiNavigationService
yang digunakan untuk melakukan navigasi halaman view-model-first.
Catatan
Aplikasi MauiNavigationService
yang digunakan sederhana dan tidak mencakup semua jenis navigasi yang mungkin. Jenis navigasi yang diperlukan oleh aplikasi Anda mungkin memerlukan fungsionalitas tambahan.
Menavigasi antar halaman
Logika navigasi dapat berada di tampilan kode belakang atau model tampilan terikat data. Meskipun menempatkan logika navigasi dalam tampilan mungkin merupakan pendekatan yang paling mudah, itu tidak mudah diuji melalui pengujian unit. Menempatkan logika navigasi dalam kelas model tampilan berarti bahwa logika dapat diverifikasi melalui pengujian unit. Selain itu, model tampilan kemudian dapat menerapkan logika untuk mengontrol navigasi untuk memastikan bahwa aturan bisnis tertentu diberlakukan. Misalnya, aplikasi mungkin tidak mengizinkan pengguna untuk menavigasi jauh dari halaman tanpa terlebih dahulu memastikan bahwa data yang dimasukkan valid.
Layanan navigasi biasanya dipanggil dari model tampilan, untuk mempromosikan uji coba. Namun, menavigasi ke tampilan dari model tampilan akan mengharuskan model tampilan untuk mereferensikan tampilan, dan terutama melihat bahwa model tampilan aktif tidak terkait dengan, yang tidak disarankan. Oleh karena itu, yang MauiNavigationService
disajikan di sini menentukan jenis model tampilan sebagai target untuk dinavigasi.
Aplikasi multi-platform eShop menggunakan MauiNavigationService
kelas untuk menyediakan navigasi view-model-first. Kelas ini mengimplementasikan INavigationService
antarmuka, yang ditunjukkan dalam contoh kode berikut:
public interface INavigationService
{
Task InitializeAsync();
Task NavigateToAsync(string route, IDictionary<string, object> routeParameters = null);
Task PopAsync();
}
Antarmuka ini menentukan bahwa kelas penerapan harus menyediakan metode berikut:
Metode | Tujuan |
---|---|
InitializeAsync |
Melakukan navigasi ke salah satu dari dua halaman saat aplikasi diluncurkan. |
NavigateToAsync(string route, IDictionary<string, object> routeParameters = null) |
Melakukan navigasi hierarkis ke halaman tertentu menggunakan rute navigasi terdaftar. Dapat secara opsional meneruskan parameter rute bernama yang akan digunakan untuk diproses di halaman tujuan |
PopAsync |
Menghapus halaman saat ini dari tumpukan navigasi. |
Catatan
Antarmuka INavigationService
biasanya juga akan menentukan GoBackAsync
metode, yang digunakan untuk kembali secara terprogram ke halaman sebelumnya di tumpukan navigasi. Namun, metode ini hilang dari aplikasi multi-platform eShop karena tidak diperlukan.
Membuat instans MauiNavigationService
Kelas MauiNavigationService
, yang mengimplementasikan INavigationService
antarmuka, terdaftar sebagai singleton dengan kontainer injeksi dependensi dalam MauiProgram.CreateMauiApp()
metode , seperti yang ditunjukkan dalam contoh kode berikut:
mauiAppBuilder.Services.AddSingleton<INavigationService, MauiNavigationService>();
Antarmuka INavigationService
kemudian dapat diselesaikan dengan menambahkannya ke konstruktor tampilan dan model tampilan kami, seperti yang ditunjukkan dalam contoh kode berikut:
public AppShell(INavigationService navigationService)
Ini mengembalikan referensi ke MauiNavigationService
objek yang disimpan dalam kontainer injeksi dependensi.
Kelas ViewModelBase
menyimpan instans MauiNavigationService
dalam NavigationService
properti, dari jenis INavigationService
. Oleh karena itu, semua kelas model tampilan, yang berasal dari ViewModelBase
kelas, dapat menggunakan NavigationService
properti untuk mengakses metode yang ditentukan oleh INavigationService
antarmuka.
Menangani permintaan navigasi
.NET MAUI menyediakan beberapa cara untuk menavigasi dalam aplikasi. Cara tradisional untuk menavigasi adalah dengan NavigationPage
kelas , yang mengimplementasikan pengalaman navigasi hierarkis di mana pengguna dapat menavigasi melalui halaman, maju dan mundur, seperti yang diinginkan. Aplikasi eShop menggunakan Shell
komponen sebagai kontainer akar untuk aplikasi dan sebagai host navigasi. Untuk informasi selengkapnya tentang navigasi Shell, lihat Navigasi Shell di Pusat Pengembang Microsoft.
Navigasi dilakukan di dalam kelas model tampilan dengan memanggil salah NavigateToAsync
satu metode, menentukan jalur rute untuk halaman yang dinavigasi, seperti yang ditunjukkan dalam contoh kode berikut:
await NavigationService.NavigateToAsync("//Main");
Contoh kode berikut menunjukkan metode yang NavigateToAsync
disediakan oleh MauiNavigationService
kelas:
public Task NavigateToAsync(string route, IDictionary<string, object> routeParameters = null)
{
return
routeParameters != null
? Shell.Current.GoToAsync(route, routeParameters)
: Shell.Current.GoToAsync(route);
}
Kontrol .NET MAUIShell
sudah terbiasa dengan navigasi berbasis rute, sehingga NavigateToAsync
metode ini berfungsi untuk menutupi fungsionalitas ini. Metode ini NavigateToAsync
memungkinkan data navigasi ditentukan sebagai argumen yang diteruskan ke model tampilan yang dinavigasi, di mana biasanya digunakan untuk melakukan inisialisasi. Untuk informasi selengkapnya, lihat Meneruskan parameter selama navigasi.
Penting
Ada beberapa cara untuk melakukan navigasi di .NET MAUI. MauiNavigationService
secara khusus dibangun untuk bekerja dengan Shell
. Jika Anda menggunakan NavigationPage
atau TabbedPage
atau mekanisme navigasi yang berbeda, layanan perutean ini harus diperbarui untuk bekerja menggunakan komponen tersebut.
Untuk mendaftarkan rute untuk MauiNavigationService
kita perlu menyediakan informasi rute dari XAML atau di kode-belakang. Contoh berikut menunjukkan pendaftaran rute melalui XAML.
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:eShop.Views"
x:Class="eShop.AppShell">
<!-- Omitted for brevity -->
<FlyoutItem >
<ShellContent x:Name="login" ContentTemplate="{DataTemplate views:LoginView}" Route="Login" />
</FlyoutItem>
<TabBar x:Name="main" Route="Main">
<ShellContent Title="CATALOG" Route="Catalog" Icon="{StaticResource CatalogIconImageSource}" ContentTemplate="{DataTemplate views:CatalogView}" />
<ShellContent Title="PROFILE" Route="Profile" Icon="{StaticResource ProfileIconImageSource}" ContentTemplate="{DataTemplate views:ProfileView}" />
</TabBar>
</Shell>
Dalam contoh ini, ShellContent
objek antarmuka pengguna dan TabBar
mengatur properti mereka Route
. Ini adalah metode yang disukai untuk mendaftarkan rute untuk objek antarmuka pengguna yang dikendalikan oleh Shell
.
Jika kita memiliki objek yang akan ditambahkan ke tumpukan navigasi di lain waktu, maka kita perlu menambahkannya melalui code-behind. Contoh berikut menunjukkan pendaftaran rute di code-behind.
Routing.RegisterRoute("Filter", typeof(FiltersView));
Routing.RegisterRoute("Basket", typeof(BasketView));
Di code-behind, kita akan memanggil Routing.RegisterRoute
metode yang mengambil nama rute sebagai parameter pertama dan jenis tampilan sebagai parameter kedua. Saat model tampilan menggunakan NavigationService
properti untuk menavigasi, objek aplikasi Shell
akan mencari rute terdaftar dan mendorongnya ke tumpukan navigasi.
Setelah tampilan dibuat dan dinavigasi, ApplyQueryAttributes
metode dan InitializeAsync
dari model tampilan terkait tampilan dijalankan. Untuk informasi selengkapnya, lihat Meneruskan parameter selama navigasi.
Menavigasi saat aplikasi diluncurkan
Saat aplikasi diluncurkan, Shell
objek diatur sebagai tampilan akar aplikasi. Setelah diatur, Shell
akan digunakan untuk mengontrol pendaftaran rute dan akan ada di akar aplikasi kami ke depannya. Shell
Setelah dibuat, kita dapat menunggunya dilampirkan ke aplikasi menggunakan OnParentSet
metode untuk menginisialisasi rute navigasi kita. Contoh kode berikut menunjukkan metode ini:
protected override async void OnParentSet()
{
base.OnParentSet();
if (Parent is not null)
{
await _navigationService.InitializeAsync();
}
}
Metode ini menggunakan instans INavigationService
yang disediakan konstruktor dari injeksi dependensi dan memanggil metodenya InitializeAsync
.
Contoh kode berikut menunjukkan implementasi MauiNavigationService.InitializeAsync
metode :
public Task InitializeAsync()
{
return NavigateToAsync(string.IsNullOrEmpty(_settingsService.AuthAccessToken)
? "//Login"
: "//Main/Catalog");
}
Rute //Main/Catalog
dinavigasi ke jika aplikasi memiliki token akses cache, yang digunakan untuk autentikasi. Jika tidak, //Login
rute akan dinavigasi.
Meneruskan parameter selama navigasi
Metode NavigateToAsync
, yang ditentukan oleh INavigationService
antarmuka, memungkinkan data navigasi ditentukan sebagai IDictionary<string, object>
data yang diteruskan ke model tampilan yang dinavigasi, tempat biasanya digunakan untuk melakukan inisialisasi.
Misalnya, ProfileViewModel
kelas berisi OrderDetailCommand
yang dijalankan saat pengguna memilih pesanan di ProfileView
halaman. Pada gilirannya OrderDetailAsync
, ini menjalankan metode , yang ditunjukkan dalam contoh kode berikut:
private async Task OrderDetailAsync(Order order)
{
if (order is null)
{
return;
}
await NavigationService.NavigateToAsync(
"OrderDetail",
new Dictionary<string, object>{ { "OrderNumber", order.OrderNumber } });
}
Metode ini memanggil navigasi ke OrderDetail
rute, meneruskan informasi nomor pesanan urutan yang dipilih pengguna. Ketika kerangka kerja injeksi dependensi membuat OrderDetailView
untuk OrderDetail
rute bersama dengan OrderDetailViewModel
kelas yang ditetapkan ke tampilan BindingContext
. OrderDetailViewModel
memiliki atribut yang ditambahkan ke dalamnya yang memungkinkannya menerima data dari layanan navigasi seperti yang ditunjukkan pada contoh kode di bawah ini.
[QueryProperty(nameof(OrderNumber), "OrderNumber")]
public class OrderDetailViewModel : ViewModelBase
{
public int OrderNumber { get; set; }
}
Atribut memungkinkan QueryProperty
kita untuk memberikan parameter untuk properti untuk memetakan nilai ke dan kunci untuk menemukan nilai dari kamus parameter kueri. Dalam contoh ini, kunci "OrderNumber" dan nilai nomor pesanan disediakan selama NavigateToAsync
panggilan. Model tampilan menemukan kunci "OrderNumber" dan memetakan nilai ke OrderNumber
properti . Properti OrderNumber
kemudian dapat digunakan di lain waktu untuk mengambil detail pesanan lengkap dari OrderService
instans.
Memanggil navigasi menggunakan perilaku
Navigasi biasanya dipicu dari tampilan oleh interaksi pengguna. Misalnya, LoginView
navigasi melakukan setelah autentikasi berhasil. Contoh kode berikut menunjukkan bagaimana navigasi dipanggil oleh perilaku:
<WebView>
<WebView.Behaviors>
<behaviors:EventToCommandBehavior
EventName="Navigating"
EventArgsConverter="{StaticResource WebNavigatingEventArgsConverter}"
Command="{Binding NavigateCommand}" />
</WebView.Behaviors>
</WebView>
Pada runtime, EventToCommandBehavior
akan merespons interaksi dengan WebView
. WebView
Ketika menavigasi ke halaman web, Navigating
peristiwa akan diaktifkan, yang akan menjalankan NavigateCommand
di LoginViewMode
l. Secara default, argumen peristiwa untuk peristiwa diteruskan ke perintah . Data ini dikonversi karena diteruskan antara sumber dan target oleh pengonversi yang ditentukan dalam EventArgsConverter
properti , yang mengembalikan Url
dari WebNavigatingEventArgs
. Oleh karena itu, ketika NavigationCommand
dijalankan, Url
halaman web diteruskan sebagai parameter ke Tindakan terdaftar.
Pada gilirannya, menjalankan NavigationCommand
NavigateAsync
metode , yang ditunjukkan dalam contoh kode berikut:
private async Task NavigateAsync(string url)
{
// Omitted for brevity.
if (!string.IsNullOrWhiteSpace(accessToken))
{
_settingsService.AuthAccessToken = accessToken;
_settingsService.AuthIdToken = authResponse.IdentityToken;
await NavigationService.NavigateToAsync("//Main/Catalog");
}
}
Metode ini memanggil NavigationService
rute aplikasi ke //Main/Catalog
rute.
Mengonfirmasi atau membatalkan navigasi
Aplikasi mungkin perlu berinteraksi dengan pengguna selama operasi navigasi, sehingga pengguna dapat mengonfirmasi atau membatalkan navigasi. Ini mungkin diperlukan, misalnya, ketika pengguna mencoba menavigasi sebelum menyelesaikan halaman entri data sepenuhnya. Dalam situasi ini, aplikasi harus memberikan pemberitahuan yang memungkinkan pengguna untuk menavigasi jauh dari halaman, atau untuk membatalkan operasi navigasi sebelum terjadi. Ini dapat dicapai dalam kelas model tampilan dengan menggunakan respons dari pemberitahuan untuk mengontrol apakah navigasi dipanggil atau tidak.
Ringkasan
.NET MAUI menyertakan dukungan untuk navigasi halaman, yang biasanya dihasilkan dari interaksi pengguna dengan UI, atau dari aplikasi itu sendiri, sebagai akibat dari perubahan status berbasis logika internal. Namun, navigasi bisa rumit untuk diterapkan di aplikasi yang menggunakan pola MVVM.
Bab ini menyajikan kelas NavigationService, yang digunakan untuk melakukan navigasi view-model-first dari view-models. Menempatkan logika navigasi dalam kelas model tampilan berarti bahwa logika dapat dilakukan melalui pengujian otomatis. Selain itu, model tampilan kemudian dapat menerapkan logika untuk mengontrol navigasi untuk memastikan bahwa aturan bisnis tertentu diberlakukan.