Router
Pendahuluan
Rute memungkinkan Anda mendefinisikan halaman-halaman berbeda di aplikasi Anda dan menavigasi di antaranya.
Gunakan rute ketika Anda perlu:
- Mendefinisikan halaman yang tersedia di aplikasi Anda
- Menavigasi pengguna antar layar
- Melindungi halaman di balik autentikasi
- Mengirim data dari satu halaman ke halaman lain
- Menangani deep link dari URL
Anda dapat menambahkan rute di dalam file lib/routes/router.dart.
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(PostsPage.path);
router.add(PostDetailPage.path);
// add more routes
// router.add(AccountPage.path);
});
Tip: Anda dapat membuat rute secara manual atau menggunakan alat CLI Metro untuk membuatnya secara otomatis.
Berikut adalah contoh membuat halaman 'account' menggunakan Metro.
metro make:page account_page
// Adds your new route automatically to /lib/routes/router.dart
appRouter() => nyRoutes((router) {
...
router.add(AccountPage.path);
});
Anda mungkin juga perlu mengirim data dari satu tampilan ke tampilan lainnya. Di Nylo Website, hal ini dimungkinkan menggunakan NyStatefulWidget (widget stateful dengan akses data rute bawaan). Kita akan membahas lebih dalam untuk menjelaskan cara kerjanya.
Menambahkan rute
Ini adalah cara termudah untuk menambahkan rute baru ke proyek Anda.
Jalankan perintah di bawah ini untuk membuat halaman baru.
metro make:page profile_page
Setelah menjalankan perintah di atas, akan dibuat Widget baru bernama ProfilePage dan ditambahkan ke direktori resources/pages/ Anda.
Perintah ini juga akan menambahkan rute baru ke file lib/routes/router.dart Anda.
File: /lib/routes/router.dart
appRouter() => nyRoutes((router) {
...
router.add(HomePage.path).initialRoute();
// My new route
router.add(ProfilePage.path);
});
Navigasi ke halaman
Anda dapat menavigasi ke halaman baru menggunakan helper routeTo.
void _pressedSettings() {
routeTo(SettingsPage.path);
}
Rute awal
Di router Anda, Anda dapat mendefinisikan halaman pertama yang harus dimuat menggunakan metode .initialRoute().
Setelah Anda menetapkan rute awal, halaman tersebut akan menjadi halaman pertama yang dimuat saat Anda membuka aplikasi.
appRouter() => nyRoutes((router) {
router.add(HomePage.path);
router.add(SettingsPage.path);
router.add(ProfilePage.path).initialRoute();
// new initial route
});
Rute Awal Bersyarat
Anda juga dapat menetapkan rute awal bersyarat menggunakan parameter when:
appRouter() => nyRoutes((router) {
router.add(OnboardingPage.path).initialRoute(
when: () => !hasCompletedOnboarding()
);
router.add(HomePage.path).initialRoute(
when: () => hasCompletedOnboarding()
);
});
Navigasi ke Rute Awal
Gunakan routeToInitial() untuk menavigasi ke rute awal aplikasi:
void _goHome() {
routeToInitial();
}
Ini akan menavigasi ke rute yang ditandai dengan .initialRoute() dan menghapus tumpukan navigasi.
Rute Pratinjau
Selama pengembangan, Anda mungkin ingin melihat pratinjau halaman tertentu dengan cepat tanpa mengubah rute awal secara permanen. Gunakan .previewRoute() untuk sementara menjadikan rute mana pun sebagai rute awal:
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(SettingsPage.path);
router.add(ProfilePage.path).previewRoute(); // This will be shown first during development
});
Metode previewRoute():
- Menggantikan pengaturan
initialRoute()danauthenticatedRoute()yang ada - Menjadikan rute yang ditentukan sebagai rute awal
- Berguna untuk menguji halaman tertentu dengan cepat selama pengembangan
Peringatan: Ingat untuk menghapus
.previewRoute()sebelum merilis aplikasi Anda!
Rute Terautentikasi
Di aplikasi Anda, Anda dapat mendefinisikan rute untuk menjadi rute awal ketika pengguna sudah terautentikasi. Ini akan secara otomatis menggantikan rute awal default dan menjadi halaman pertama yang dilihat pengguna saat mereka masuk.
Pertama, pengguna Anda harus masuk menggunakan helper Auth.authenticate({...}).
Sekarang, saat mereka membuka aplikasi, rute yang Anda definisikan akan menjadi halaman default sampai mereka keluar.
appRouter() => nyRoutes((router) {
router.add(IntroPage.path).initialRoute();
router.add(LoginPage.path);
router.add(ProfilePage.path).authenticatedRoute();
// auth page
});
Rute Terautentikasi Bersyarat
Anda juga dapat menetapkan rute terautentikasi bersyarat:
router.add(ProfilePage.path).authenticatedRoute(
when: () => hasCompletedSetup()
);
Navigasi ke Rute Terautentikasi
Anda dapat menavigasi ke halaman terautentikasi menggunakan helper routeToAuthenticatedRoute():
routeToAuthenticatedRoute();
Lihat juga: Autentikasi untuk detail tentang mengautentikasi pengguna dan mengelola sesi.
Rute Tidak Dikenal
Anda dapat mendefinisikan rute untuk menangani skenario 404/tidak ditemukan menggunakan .unknownRoute():
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(NotFoundPage.path).unknownRoute();
});
Ketika pengguna menavigasi ke rute yang tidak ada, mereka akan ditampilkan halaman rute tidak dikenal.
Route guards
Route guards melindungi halaman dari akses yang tidak sah. Mereka berjalan sebelum navigasi selesai, memungkinkan Anda mengalihkan pengguna atau memblokir akses berdasarkan kondisi.
Gunakan route guards ketika Anda perlu:
- Melindungi halaman dari pengguna yang belum terautentikasi
- Memeriksa izin sebelum mengizinkan akses
- Mengalihkan pengguna berdasarkan kondisi (misalnya, onboarding belum selesai)
- Mencatat atau melacak tampilan halaman
Untuk membuat Route Guard baru, jalankan perintah di bawah ini.
metro make:route_guard dashboard
Selanjutnya, tambahkan Route Guard baru ke rute Anda.
// File: /routes/router.dart
appRouter() => nyRoutes((router) {
router.add(HomePage.path);
router.add(LoginPage.path);
router.add(DashboardPage.path,
routeGuards: [
DashboardRouteGuard() // Add your guard
]
); // restricted page
});
Anda juga dapat mengatur route guards menggunakan metode addRouteGuard:
// File: /routes/router.dart
appRouter() => nyRoutes((router) {
router.add(DashboardPage.path)
.addRouteGuard(MyRouteGuard());
// or add multiple guards
router.add(DashboardPage.path)
.addRouteGuards([MyRouteGuard(), MyOtherRouteGuard()]);
})
Siklus Hidup NyRouteGuard
Di v7, route guards menggunakan kelas NyRouteGuard dengan tiga metode siklus hidup:
onBefore(RouteContext context)- Dipanggil sebelum navigasi. Kembalikannext()untuk melanjutkan,redirect()untuk pergi ke tempat lain, atauabort()untuk menghentikan.onAfter(RouteContext context)- Dipanggil setelah navigasi berhasil ke rute.
Contoh Dasar
File: /routes/guards/dashboard_route_guard.dart
class DashboardRouteGuard extends NyRouteGuard {
DashboardRouteGuard();
@override
Future<GuardResult> onBefore(RouteContext context) async {
// Perform a check if they can access the page
bool userLoggedIn = await Auth.isAuthenticated();
if (userLoggedIn == false) {
return redirect(LoginPage.path);
}
return next();
}
@override
Future<void> onAfter(RouteContext context) async {
// Track page view after successful navigation
Analytics.trackPageView(context.routeName);
}
}
RouteContext
Kelas RouteContext menyediakan akses ke informasi navigasi:
| Properti | Tipe | Deskripsi |
|---|---|---|
context |
BuildContext? |
Build context saat ini |
data |
dynamic |
Data yang dikirim ke rute |
queryParameters |
Map<String, String> |
Parameter query URL |
routeName |
String |
Nama/path rute |
originalRouteName |
String? |
Nama rute asli sebelum transformasi |
@override
Future<GuardResult> onBefore(RouteContext context) async {
print('Navigating to: ${context.routeName}');
print('Query params: ${context.queryParameters}');
print('Route data: ${context.data}');
return next();
}
Metode Bantuan Guard
next()
Lanjutkan ke guard berikutnya atau ke rute:
@override
Future<GuardResult> onBefore(RouteContext context) async {
return next(); // Allow navigation to continue
}
redirect()
Arahkan ulang ke rute yang berbeda:
@override
Future<GuardResult> onBefore(RouteContext context) async {
if (!isLoggedIn) {
return redirect(
LoginPage.path,
data: {'returnTo': context.routeName},
navigationType: NavigationType.pushReplace,
);
}
return next();
}
Metode redirect() menerima:
| Parameter | Tipe | Deskripsi |
|---|---|---|
path |
Object |
Path rute atau RouteView |
data |
dynamic |
Data yang dikirim ke rute |
queryParameters |
Map<String, dynamic>? |
Parameter query |
navigationType |
NavigationType |
Tipe navigasi (default: pushReplace) |
transitionType |
TransitionType? |
Transisi halaman |
onPop |
Function(dynamic)? |
Callback saat rute di-pop |
abort()
Hentikan navigasi tanpa pengalihan:
@override
Future<GuardResult> onBefore(RouteContext context) async {
if (isMaintenanceMode) {
showMaintenanceDialog();
return abort(); // User stays on current route
}
return next();
}
setData()
Modifikasi data yang dikirim ke guard berikutnya dan rute:
@override
Future<GuardResult> onBefore(RouteContext context) async {
final user = await fetchUser();
setData({'user': user, ...?context.data});
return next();
}
Guard Berparameter
Gunakan ParameterizedGuard ketika Anda perlu mengonfigurasi perilaku guard per rute:
class RoleGuard extends ParameterizedGuard<List<String>> {
RoleGuard(super.params);
@override
Future<GuardResult> onBefore(RouteContext context) async {
final user = await Auth.user();
if (!params.any((role) => user.hasRole(role))) {
return redirect('/unauthorized');
}
return next();
}
}
// Usage:
router.add(AdminPage.path, routeGuards: [
RoleGuard(['admin', 'moderator'])
]);
Guard Stacks
Gabungkan beberapa guard menjadi satu guard yang dapat digunakan kembali menggunakan GuardStack:
// Create reusable guard combinations
final adminGuards = GuardStack([
AuthGuard(),
RoleGuard(['admin']),
AuditLogGuard(),
]);
router.add(AdminPage.path, routeGuards: [adminGuards]);
Guard Bersyarat
Terapkan guard secara bersyarat berdasarkan predikat:
router.add(DashboardPage.path, routeGuards: [
ConditionalGuard(
condition: (context) => context.routeName.startsWith('/admin'),
guard: AdminGuard(),
)
]);
Mengirim data ke halaman lain
Di bagian ini, kami akan menunjukkan bagaimana Anda dapat mengirim data dari satu widget ke widget lainnya.
Dari Widget Anda, gunakan helper routeTo dan kirim data yang ingin Anda kirim ke halaman baru.
// HomePage Widget
void _pressedSettings() {
routeTo(SettingsPage.path, data: "Hello World");
}
...
// SettingsPage Widget (other page)
class _SettingsPageState extends NyPage<SettingsPage> {
...
@override
get init => () {
print(widget.data()); // Hello World
// or
print(data()); // Hello World
};
Contoh lainnya
// Home page widget
class _HomePageState extends NyPage<HomePage> {
_showProfile() {
User user = new User();
user.firstName = 'Anthony';
routeTo(ProfilePage.path, data: user);
}
...
// Profile page widget (other page)
class _ProfilePageState extends NyPage<ProfilePage> {
@override
get init => () {
User user = widget.data();
print(user.firstName); // Anthony
};
Grup Rute
Grup rute mengorganisir rute-rute terkait dan menerapkan pengaturan bersama. Mereka berguna ketika beberapa rute membutuhkan guard, prefix URL, atau gaya transisi yang sama.
Gunakan grup rute ketika Anda perlu:
- Menerapkan route guard yang sama ke beberapa halaman
- Menambahkan prefix URL ke sekumpulan rute (misalnya,
/admin/...) - Mengatur transisi halaman yang sama untuk rute-rute terkait
Anda dapat mendefinisikan grup rute seperti pada contoh di bawah ini.
appRouter() => nyRoutes((router) {
...
router.group(() => {
"route_guards": [AuthRouteGuard()],
"prefix": "/dashboard",
"transition_type": TransitionType.fade(),
}, (router) {
router.add(ChatPage.path);
router.add(FollowersPage.path);
});
Pengaturan opsional untuk grup rute adalah:
| Pengaturan | Tipe | Deskripsi |
|---|---|---|
route_guards |
List<RouteGuard> |
Terapkan route guards ke semua rute dalam grup |
prefix |
String |
Tambahkan prefix ke semua path rute dalam grup |
transition_type |
TransitionType |
Atur transisi untuk semua rute dalam grup |
transition |
PageTransitionType |
Atur tipe transisi halaman (tidak digunakan lagi, gunakan transition_type) |
transition_settings |
PageTransitionSettings |
Atur pengaturan transisi |
Menggunakan Parameter Rute
Ketika Anda membuat halaman baru, Anda dapat memperbarui rute untuk menerima parameter.
class ProfilePage extends NyStatefulWidget<HomeController> {
static RouteView path = ("/profile/{userId}", (_) => ProfilePage());
ProfilePage() : super(child: () => _ProfilePageState());
}
Sekarang, saat Anda menavigasi ke halaman tersebut, Anda dapat mengirim userId
routeTo(ProfilePage.path.withParams({"userId": 7}));
Anda dapat mengakses parameter di halaman baru seperti ini.
class _ProfilePageState extends NyPage<ProfilePage> {
@override
get init => () {
print(widget.queryParameters()); // {"userId": 7}
};
}
Query Parameters
Saat menavigasi ke halaman baru, Anda juga dapat memberikan query parameters.
Mari kita lihat.
// Home page
routeTo(ProfilePage.path, queryParameters: {"user": "7"});
// navigate to profile page
...
// Profile Page
@override
get init => () {
print(widget.queryParameters()); // {"user": 7}
// or
print(queryParameters()); // {"user": 7}
};
Catatan: Selama widget halaman Anda meng-extend
NyStatefulWidgetdan kelasNyPage, maka Anda dapat memanggilwidget.queryParameters()untuk mengambil semua query parameters dari nama rute.
// Example page
routeTo(ProfilePage.path, queryParameters: {"hello": "world", "say": "I love code"});
...
// Home page
class MyHomePage extends NyStatefulWidget<HomeController> {
...
}
class _MyHomePageState extends NyPage<MyHomePage> {
@override
get init => () {
widget.queryParameters(); // {"hello": "World", "say": "I love code"}
// or
queryParameters(); // {"hello": "World", "say": "I love code"}
};
Tip: Query parameters harus mengikuti protokol HTTP, Contoh: /account?userId=1&tab=2
Transisi Halaman
Anda dapat menambahkan transisi saat menavigasi dari satu halaman dengan memodifikasi file router.dart Anda.
import 'package:page_transition/page_transition.dart';
appRouter() => nyRoutes((router) {
// bottomToTop
router.add(SettingsPage.path,
transitionType: TransitionType.bottomToTop()
);
// fade
router.add(HomePage.path,
transitionType: TransitionType.fade()
);
});
Transisi Halaman yang Tersedia
Transisi Dasar
TransitionType.fade()- Memfadekan halaman baru masuk sambil memfadekan halaman lama keluarTransitionType.theme()- Menggunakan tema transisi halaman dari tema aplikasi
Transisi Geser Arah
TransitionType.rightToLeft()- Menggeser dari tepi kanan layarTransitionType.leftToRight()- Menggeser dari tepi kiri layarTransitionType.topToBottom()- Menggeser dari tepi atas layarTransitionType.bottomToTop()- Menggeser dari tepi bawah layar
Transisi Geser dengan Fade
TransitionType.rightToLeftWithFade()- Menggeser dan memfadekan dari tepi kananTransitionType.leftToRightWithFade()- Menggeser dan memfadekan dari tepi kiri
Transisi Transformasi
TransitionType.scale(alignment: ...)- Menskalakan dari titik alignment yang ditentukanTransitionType.rotate(alignment: ...)- Memutar di sekitar titik alignment yang ditentukanTransitionType.size(alignment: ...)- Membesar dari titik alignment yang ditentukan
Transisi Joined (Memerlukan widget saat ini)
TransitionType.leftToRightJoined(childCurrent: ...)- Halaman saat ini keluar ke kanan sementara halaman baru masuk dari kiriTransitionType.rightToLeftJoined(childCurrent: ...)- Halaman saat ini keluar ke kiri sementara halaman baru masuk dari kananTransitionType.topToBottomJoined(childCurrent: ...)- Halaman saat ini keluar ke bawah sementara halaman baru masuk dari atasTransitionType.bottomToTopJoined(childCurrent: ...)- Halaman saat ini keluar ke atas sementara halaman baru masuk dari bawah
Transisi Pop (Memerlukan widget saat ini)
TransitionType.leftToRightPop(childCurrent: ...)- Halaman saat ini keluar ke kanan, halaman baru tetap di tempatTransitionType.rightToLeftPop(childCurrent: ...)- Halaman saat ini keluar ke kiri, halaman baru tetap di tempatTransitionType.topToBottomPop(childCurrent: ...)- Halaman saat ini keluar ke bawah, halaman baru tetap di tempatTransitionType.bottomToTopPop(childCurrent: ...)- Halaman saat ini keluar ke atas, halaman baru tetap di tempat
Transisi Material Design Shared Axis
TransitionType.sharedAxisHorizontal()- Transisi geser dan fade horizontalTransitionType.sharedAxisVertical()- Transisi geser dan fade vertikalTransitionType.sharedAxisScale()- Transisi skala dan fade
Parameter Kustomisasi
Setiap transisi menerima parameter opsional berikut:
| Parameter | Deskripsi | Default |
|---|---|---|
curve |
Kurva animasi | Kurva spesifik platform |
duration |
Durasi animasi | Durasi spesifik platform |
reverseDuration |
Durasi animasi mundur | Sama dengan duration |
fullscreenDialog |
Apakah rute merupakan dialog fullscreen | false |
opaque |
Apakah rute bersifat opaque | false |
// Home page widget
class _HomePageState extends NyPage<HomePage> {
_showProfile() {
routeTo(ProfilePage.path,
transitionType: TransitionType.bottomToTop()
);
}
...
Tipe Navigasi
Saat menavigasi, Anda dapat menentukan salah satu dari berikut ini jika Anda menggunakan helper routeTo.
| Tipe | Deskripsi |
|---|---|
NavigationType.push |
Mendorong halaman baru ke tumpukan rute aplikasi Anda |
NavigationType.pushReplace |
Mengganti rute saat ini, menghapus rute sebelumnya setelah rute baru selesai |
NavigationType.popAndPushNamed |
Menghapus rute saat ini dari navigator dan mendorong rute bernama sebagai gantinya |
NavigationType.pushAndRemoveUntil |
Mendorong dan menghapus rute sampai predikat bernilai true |
NavigationType.pushAndForgetAll |
Mendorong ke halaman baru dan menghapus semua halaman lain pada tumpukan rute |
// Home page widget
class _HomePageState extends NyPage<HomePage> {
_showProfile() {
routeTo(
ProfilePage.path,
navigationType: NavigationType.pushReplace
);
}
...
Navigasi kembali
Setelah Anda berada di halaman baru, Anda dapat menggunakan helper pop() untuk kembali ke halaman sebelumnya.
// SettingsPage Widget
class _SettingsPageState extends NyPage<SettingsPage> {
_back() {
pop();
// or
Navigator.pop(context);
}
...
Jika Anda ingin mengembalikan nilai ke widget sebelumnya, berikan result seperti pada contoh di bawah ini.
// SettingsPage Widget
class _SettingsPageState extends NyPage<SettingsPage> {
_back() {
pop(result: {"status": "COMPLETE"});
}
...
// Get the value from the previous widget using the `onPop` parameter
// HomePage Widget
class _HomePageState extends NyPage<HomePage> {
_viewSettings() {
routeTo(SettingsPage.path, onPop: (value) {
print(value); // {"status": "COMPLETE"}
});
}
...
Navigasi Bersyarat
Gunakan routeIf() untuk menavigasi hanya ketika suatu kondisi terpenuhi:
// Only navigate if the user is logged in
routeIf(isLoggedIn, DashboardPage.path);
// With additional options
routeIf(
hasPermission('view_reports'),
ReportsPage.path,
data: {'filters': defaultFilters},
navigationType: NavigationType.push,
);
Jika kondisinya bernilai false, tidak ada navigasi yang terjadi.
Riwayat Rute
Di Nylo Website, Anda dapat mengakses informasi riwayat rute menggunakan helper di bawah ini.
// Get route history
Nylo.getRouteHistory(); // List<dynamic>
// Get the current route
Nylo.getCurrentRoute(); // Route<dynamic>?
// Get the previous route
Nylo.getPreviousRoute(); // Route<dynamic>?
// Get the current route name
Nylo.getCurrentRouteName(); // String?
// Get the previous route name
Nylo.getPreviousRouteName(); // String?
// Get the current route arguments
Nylo.getCurrentRouteArguments(); // dynamic
// Get the previous route arguments
Nylo.getPreviousRouteArguments(); // dynamic
Memperbarui Route Stack
Anda dapat memperbarui tumpukan navigasi secara programatis menggunakan NyNavigator.updateStack():
// Update the stack with a list of routes
NyNavigator.updateStack([
HomePage.path,
SettingsPage.path,
ProfilePage.path,
], replace: true);
// Pass data to specific routes
NyNavigator.updateStack([
HomePage.path,
ProfilePage.path,
],
replace: true,
dataForRoute: {
ProfilePage.path: {"userId": 42}
}
);
| Parameter | Tipe | Default | Deskripsi |
|---|---|---|---|
routes |
List<String> |
wajib | Daftar path rute untuk dinavigasi |
replace |
bool |
true |
Apakah mengganti tumpukan saat ini |
dataForRoute |
Map<String, dynamic>? |
null |
Data yang dikirim ke rute tertentu |
Ini berguna untuk:
- Skenario deep linking
- Memulihkan state navigasi
- Membangun alur navigasi yang kompleks
Deep Linking
Deep linking memungkinkan pengguna menavigasi langsung ke konten tertentu dalam aplikasi Anda menggunakan URL. Ini berguna untuk:
- Berbagi tautan langsung ke konten aplikasi tertentu
- Kampanye pemasaran yang menargetkan fitur dalam aplikasi tertentu
- Menangani notifikasi yang harus membuka layar aplikasi tertentu
- Transisi web-ke-aplikasi yang mulus
Setup
Sebelum mengimplementasikan deep linking di aplikasi Anda, pastikan proyek Anda dikonfigurasi dengan benar:
1. Konfigurasi Platform
iOS: Konfigurasikan universal links di proyek Xcode Anda
Android: Atur app links di AndroidManifest.xml Anda
2. Definisikan Rute Anda
Semua rute yang harus dapat diakses melalui deep links harus didaftarkan di konfigurasi router Anda:
// File: /lib/routes/router.dart
appRouter() => nyRoutes((router) {
// Basic routes
router.add(HomePage.path).initialRoute();
router.add(ProfilePage.path);
router.add(SettingsPage.path);
// Route with parameters
router.add(HotelBookingPage.path);
});
Menggunakan Deep Links
Setelah dikonfigurasi, aplikasi Anda dapat menangani URL yang masuk dalam berbagai format:
Deep Links Dasar
Navigasi sederhana ke halaman tertentu:
https://yourdomain.com/profile // Opens the profile page
https://yourdomain.com/settings // Opens the settings page
Untuk memicu navigasi ini secara programatis di dalam aplikasi Anda:
routeTo(ProfilePage.path);
routeTo(SettingsPage.path);
Path Parameters
Untuk rute yang memerlukan data dinamis sebagai bagian dari path:
Definisi Rute
class HotelBookingPage extends NyStatefulWidget {
// Define a route with a parameter placeholder {id}
static RouteView path = ("/hotel/{id}/booking", (_) => HotelBookingPage());
HotelBookingPage({super.key}) : super(child: () => _HotelBookingPageState());
}
class _HotelBookingPageState extends NyPage<HotelBookingPage> {
@override
get init => () {
// Access the path parameter
final hotelId = queryParameters()["id"]; // Returns "87" for URL ../hotel/87/booking
print("Loading hotel ID: $hotelId");
// Use the ID to fetch hotel data or perform operations
};
// Rest of your page implementation
}
Format URL
https://yourdomain.com/hotel/87/booking
Navigasi Programatis
// Navigate with parameters
routeTo(HotelBookingPage.path.withParams({"id": "87"}), queryParameters: {
"bookings": "active",
});
Query Parameters
Untuk parameter opsional atau ketika dibutuhkan beberapa nilai dinamis:
Format URL
https://yourdomain.com/profile?user=20&tab=posts
https://yourdomain.com/hotel/87/booking?checkIn=2025-04-10&nights=3
Mengakses Query Parameters
class _ProfilePageState extends NyPage<ProfilePage> {
@override
get init => () {
// Get all query parameters
final params = queryParameters();
// Access specific parameters
final userId = params["user"]; // "20"
final activeTab = params["tab"]; // "posts"
// Alternative access method
final params2 = widget.queryParameters();
print(params2); // {"user": "20", "tab": "posts"}
};
}
Navigasi Programatis dengan Query Parameters
// Navigate with query parameters
routeTo(ProfilePage.path.withQueryParams({"user": "20", "tab": "posts"}));
// Combine path and query parameters
routeTo(HotelBookingPage.path.withParams({"id": "87"}), queryParameters: {
"checkIn": "2025-04-10",
"nights": "3",
});
Menangani Deep Links
Anda dapat menangani event deep link di RouteProvider Anda:
class RouteProvider implements NyProvider {
@override
setup(Nylo nylo) async {
nylo.addRouter(appRouter());
// Handle deep links
nylo.onDeepLink(_onDeepLink);
return nylo;
}
_onDeepLink(String route, Map<String, String>? data) {
print("Deep link route: $route");
print("Deep link data: $data");
// Update the route stack for deep links
if (route == ProfilePage.path) {
NyNavigator.updateStack([
HomePage.path,
ProfilePage.path,
], replace: true, dataForRoute: {
ProfilePage.path: data,
});
}
}
@override
boot(Nylo nylo) async {
nylo.initRoutes();
}
}
Menguji Deep Links
Untuk pengembangan dan pengujian, Anda dapat mensimulasikan aktivasi deep link menggunakan ADB (Android) atau xcrun (iOS):
# Android
adb shell am start -a android.intent.action.VIEW -d "https://yourdomain.com/profile?user=20" com.yourcompany.yourapp
# iOS (Simulator)
xcrun simctl openurl booted "https://yourdomain.com/profile?user=20"
Tips Debugging
- Cetak semua parameter di metode init Anda untuk memverifikasi parsing yang benar
- Uji berbagai format URL untuk memastikan aplikasi Anda menanganinya dengan benar
- Ingat bahwa query parameters selalu diterima sebagai string, konversikan ke tipe yang sesuai sesuai kebutuhan
Pola Umum
Konversi Tipe Parameter
Karena semua parameter URL dikirim sebagai string, Anda sering perlu mengonversinya:
// Converting string parameters to appropriate types
final hotelId = int.parse(queryParameters()["id"] ?? "0");
final isAvailable = (queryParameters()["available"] ?? "false") == "true";
final checkInDate = DateTime.parse(queryParameters()["checkIn"] ?? "");
Parameter Opsional
Menangani kasus di mana parameter mungkin tidak ada:
final userId = queryParameters()["user"];
if (userId != null) {
// Load specific user profile
} else {
// Load current user profile
}
// Or check hasQueryParameter
if (hasQueryParameter('status')) {
// Do something with the status parameter
} else {
// Handle absence of the parameter
}
Lanjutan
Memeriksa Apakah Rute Ada
Anda dapat memeriksa apakah rute terdaftar di router Anda:
if (Nylo.containsRoute("/profile")) {
routeTo("/profile");
}
Metode NyRouter
Kelas NyRouter menyediakan beberapa metode yang berguna:
| Metode | Deskripsi |
|---|---|
getRegisteredRouteNames() |
Mendapatkan semua nama rute terdaftar sebagai daftar |
getRegisteredRoutes() |
Mendapatkan semua rute terdaftar sebagai map |
containsRoutes(routes) |
Memeriksa apakah router berisi semua rute yang ditentukan |
getInitialRouteName() |
Mendapatkan nama rute awal |
getAuthRouteName() |
Mendapatkan nama rute terautentikasi |
getUnknownRouteName() |
Mendapatkan nama rute tidak dikenal/404 |
Mendapatkan Argumen Rute
Anda dapat mendapatkan argumen rute menggunakan NyRouter.args<T>():
class _ProfilePageState extends NyPage<ProfilePage> {
@override
Widget build(BuildContext context) {
// Get typed arguments
final args = NyRouter.args<NyArgument>(context);
final userData = args?.data;
return Scaffold(...);
}
}
NyArgument dan NyQueryParameters
Data yang dikirim antar rute dibungkus dalam kelas-kelas ini:
// NyArgument contains route data
NyArgument argument = NyArgument({'userId': 42});
print(argument.data); // {'userId': 42}
// NyQueryParameters contains URL query parameters
NyQueryParameters params = NyQueryParameters({'tab': 'posts'});
print(params.data); // {'tab': 'posts'}