Router
Einleitung
Routen ermoeglichen es Ihnen, die verschiedenen Seiten in Ihrer App zu definieren und zwischen ihnen zu navigieren.
Verwenden Sie Routen, wenn Sie:
- Die in Ihrer App verfuegbaren Seiten definieren muessen
- Benutzer zwischen Bildschirmen navigieren lassen moechten
- Seiten hinter einer Authentifizierung schuetzen moechten
- Daten von einer Seite an eine andere uebergeben muessen
- Deep Links von URLs behandeln muessen
Sie koennen Routen in der Datei lib/routes/router.dart hinzufuegen.
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(PostsPage.path);
router.add(PostDetailPage.path);
// add more routes
// router.add(AccountPage.path);
});
Tipp: Sie koennen Ihre Routen manuell erstellen oder das Metro CLI-Tool verwenden, um sie fuer Sie zu erstellen.
Hier ist ein Beispiel fuer die Erstellung einer 'account'-Seite mit Metro.
metro make:page account_page
// Adds your new route automatically to /lib/routes/router.dart
appRouter() => nyRoutes((router) {
...
router.add(AccountPage.path);
});
Moeglicherweise muessen Sie auch Daten von einer Ansicht an eine andere uebergeben. In Nylo Website ist das mit dem NyStatefulWidget (einem Stateful Widget mit integriertem Zugriff auf Routendaten) moeglich. Wir werden tiefer darauf eingehen, um zu erklaeren, wie es funktioniert.
Routen hinzufuegen
Dies ist der einfachste Weg, neue Routen zu Ihrem Projekt hinzuzufuegen.
Fuehren Sie den folgenden Befehl aus, um eine neue Seite zu erstellen.
metro make:page profile_page
Nach der Ausfuehrung wird ein neues Widget namens ProfilePage erstellt und in Ihrem Verzeichnis resources/pages/ abgelegt.
Es wird auch die neue Route zu Ihrer Datei lib/routes/router.dart hinzufuegen.
Datei: /lib/routes/router.dart
appRouter() => nyRoutes((router) {
...
router.add(HomePage.path).initialRoute();
// My new route
router.add(ProfilePage.path);
});
Zu Seiten navigieren
Sie koennen mit dem routeTo-Helfer zu neuen Seiten navigieren.
void _pressedSettings() {
routeTo(SettingsPage.path);
}
Initiale Route
In Ihren Routern koennen Sie die erste Seite festlegen, die geladen werden soll, indem Sie die .initialRoute()-Methode verwenden.
Sobald Sie die initiale Route festgelegt haben, wird sie die erste Seite sein, die beim Oeffnen der App geladen wird.
appRouter() => nyRoutes((router) {
router.add(HomePage.path);
router.add(SettingsPage.path);
router.add(ProfilePage.path).initialRoute();
// new initial route
});
Bedingte initiale Route
Sie koennen auch eine bedingte initiale Route mit dem when-Parameter festlegen:
appRouter() => nyRoutes((router) {
router.add(OnboardingPage.path).initialRoute(
when: () => !hasCompletedOnboarding()
);
router.add(HomePage.path).initialRoute(
when: () => hasCompletedOnboarding()
);
});
Zur initialen Route navigieren
Verwenden Sie routeToInitial(), um zur initialen Route der App zu navigieren:
void _goHome() {
routeToInitial();
}
Dies navigiert zur Route, die mit .initialRoute() markiert ist, und leert den Navigationsstapel.
Vorschau-Route
Waehrend der Entwicklung moechten Sie moeglicherweise schnell eine bestimmte Seite in der Vorschau anzeigen, ohne Ihre initiale Route dauerhaft zu aendern. Verwenden Sie .previewRoute(), um eine Route temporaer zur initialen Route zu machen:
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(SettingsPage.path);
router.add(ProfilePage.path).previewRoute(); // This will be shown first during development
});
Die previewRoute()-Methode:
- Ueberschreibt alle bestehenden
initialRoute()- undauthenticatedRoute()-Einstellungen - Macht die angegebene Route zur initialen Route
- Nuetzlich zum schnellen Testen bestimmter Seiten waehrend der Entwicklung
Warnung: Denken Sie daran,
.previewRoute()vor der Veroeffentlichung Ihrer App zu entfernen!
Authentifizierte Route
In Ihrer App koennen Sie eine Route definieren, die die initiale Route ist, wenn ein Benutzer authentifiziert ist. Dies ueberschreibt automatisch die Standard-initiale Route und ist die erste Seite, die der Benutzer sieht, wenn er sich anmeldet.
Zuerst sollte Ihr Benutzer mit dem Auth.authenticate({...})-Helfer eingeloggt werden.
Wenn er nun die App oeffnet, wird die von Ihnen definierte Route die Standardseite sein, bis er sich abmeldet.
appRouter() => nyRoutes((router) {
router.add(IntroPage.path).initialRoute();
router.add(LoginPage.path);
router.add(ProfilePage.path).authenticatedRoute();
// auth page
});
Bedingte authentifizierte Route
Sie koennen auch eine bedingte authentifizierte Route festlegen:
router.add(ProfilePage.path).authenticatedRoute(
when: () => hasCompletedSetup()
);
Zur authentifizierten Route navigieren
Sie koennen mit dem routeToAuthenticatedRoute()-Helfer zur authentifizierten Seite navigieren:
routeToAuthenticatedRoute();
Siehe auch: Authentifizierung fuer Details zur Benutzerauthentifizierung und Sitzungsverwaltung.
Unbekannte Route
Sie koennen eine Route definieren, die 404/Nicht-gefunden-Szenarien mit .unknownRoute() behandelt:
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(NotFoundPage.path).unknownRoute();
});
Wenn ein Benutzer zu einer Route navigiert, die nicht existiert, wird ihm die Seite der unbekannten Route angezeigt.
Route Guards
Route Guards schuetzen Seiten vor unbefugtem Zugriff. Sie werden vor Abschluss der Navigation ausgefuehrt und ermoeglichen es Ihnen, Benutzer umzuleiten oder den Zugriff basierend auf Bedingungen zu blockieren.
Verwenden Sie Route Guards, wenn Sie:
- Seiten vor nicht authentifizierten Benutzern schuetzen muessen
- Berechtigungen vor dem Zugriff pruefen muessen
- Benutzer basierend auf Bedingungen umleiten moechten (z.B. Onboarding nicht abgeschlossen)
- Seitenaufrufe protokollieren oder verfolgen moechten
Um einen neuen Route Guard zu erstellen, fuehren Sie den folgenden Befehl aus.
metro make:route_guard dashboard
Fuegen Sie als Naechstes den neuen Route Guard zu Ihrer Route hinzu.
// 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
});
Sie koennen Route Guards auch mit der addRouteGuard-Methode setzen:
// File: /routes/router.dart
appRouter() => nyRoutes((router) {
router.add(DashboardPage.path)
.addRouteGuard(MyRouteGuard());
// or add multiple guards
router.add(DashboardPage.path)
.addRouteGuards([MyRouteGuard(), MyOtherRouteGuard()]);
})
NyRouteGuard-Lebenszyklus
In v7 verwenden Route Guards die Klasse NyRouteGuard mit drei Lebenszyklusmethoden:
onBefore(RouteContext context)- Wird vor der Navigation aufgerufen. Geben Sienext()zurueck, um fortzufahren,redirect(), um umzuleiten, oderabort(), um abzubrechen.onAfter(RouteContext context)- Wird nach erfolgreicher Navigation zur Route aufgerufen.
Grundlegendes Beispiel
Datei: /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
Die Klasse RouteContext bietet Zugang zu Navigationsinformationen:
| Eigenschaft | Typ | Beschreibung |
|---|---|---|
context |
BuildContext? |
Aktueller Build-Kontext |
data |
dynamic |
An die Route uebergebene Daten |
queryParameters |
Map<String, String> |
URL-Query-Parameter |
routeName |
String |
Routenname/-pfad |
originalRouteName |
String? |
Urspruenglicher Routenname vor Transformationen |
@override
Future<GuardResult> onBefore(RouteContext context) async {
print('Navigating to: ${context.routeName}');
print('Query params: ${context.queryParameters}');
print('Route data: ${context.data}');
return next();
}
Guard-Hilfsmethoden
next()
Zum naechsten Guard oder zur Route fortfahren:
@override
Future<GuardResult> onBefore(RouteContext context) async {
return next(); // Allow navigation to continue
}
redirect()
Zu einer anderen Route umleiten:
@override
Future<GuardResult> onBefore(RouteContext context) async {
if (!isLoggedIn) {
return redirect(
LoginPage.path,
data: {'returnTo': context.routeName},
navigationType: NavigationType.pushReplace,
);
}
return next();
}
Die redirect()-Methode akzeptiert:
| Parameter | Typ | Beschreibung |
|---|---|---|
path |
Object |
Routenpfad oder RouteView |
data |
dynamic |
An die Route zu uebergebende Daten |
queryParameters |
Map<String, dynamic>? |
Query-Parameter |
navigationType |
NavigationType |
Navigationstyp (Standard: pushReplace) |
transitionType |
TransitionType? |
Seitenuebergang |
onPop |
Function(dynamic)? |
Callback beim Pop der Route |
abort()
Navigation ohne Umleitung stoppen:
@override
Future<GuardResult> onBefore(RouteContext context) async {
if (isMaintenanceMode) {
showMaintenanceDialog();
return abort(); // User stays on current route
}
return next();
}
setData()
Daten aendern, die an nachfolgende Guards und die Route uebergeben werden:
@override
Future<GuardResult> onBefore(RouteContext context) async {
final user = await fetchUser();
setData({'user': user, ...?context.data});
return next();
}
Parametrisierte Guards
Verwenden Sie ParameterizedGuard, wenn Sie das Guard-Verhalten pro Route konfigurieren muessen:
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
Kombinieren Sie mehrere Guards zu einem einzelnen wiederverwendbaren Guard mit GuardStack:
// Create reusable guard combinations
final adminGuards = GuardStack([
AuthGuard(),
RoleGuard(['admin']),
AuditLogGuard(),
]);
router.add(AdminPage.path, routeGuards: [adminGuards]);
Bedingte Guards
Wenden Sie Guards bedingt basierend auf einem Praedikat an:
router.add(DashboardPage.path, routeGuards: [
ConditionalGuard(
condition: (context) => context.routeName.startsWith('/admin'),
guard: AdminGuard(),
)
]);
Daten an eine andere Seite uebergeben
In diesem Abschnitt zeigen wir, wie Sie Daten von einem Widget an ein anderes uebergeben koennen.
Verwenden Sie in Ihrem Widget den routeTo-Helfer und uebergeben Sie die data, die Sie an die neue Seite senden moechten.
// 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
};
Weitere Beispiele
// 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
};
Routen-Gruppen
Routen-Gruppen organisieren verwandte Routen und wenden gemeinsame Einstellungen an. Sie sind nuetzlich, wenn mehrere Routen dieselben Guards, URL-Praefixe oder Uebergangsstile benoetigen.
Verwenden Sie Routen-Gruppen, wenn Sie:
- Denselben Route Guard auf mehrere Seiten anwenden moechten
- Ein URL-Praefix fuer eine Gruppe von Routen hinzufuegen moechten (z.B.
/admin/...) - Denselben Seitenuebergang fuer verwandte Routen festlegen moechten
Sie koennen eine Routen-Gruppe wie im folgenden Beispiel definieren.
appRouter() => nyRoutes((router) {
...
router.group(() => {
"route_guards": [AuthRouteGuard()],
"prefix": "/dashboard",
"transition_type": TransitionType.fade(),
}, (router) {
router.add(ChatPage.path);
router.add(FollowersPage.path);
});
Optionale Einstellungen fuer Routen-Gruppen sind:
| Einstellung | Typ | Beschreibung |
|---|---|---|
route_guards |
List<RouteGuard> |
Route Guards auf alle Routen in der Gruppe anwenden |
prefix |
String |
Ein Praefix zu allen Routenpfaden in der Gruppe hinzufuegen |
transition_type |
TransitionType |
Uebergang fuer alle Routen in der Gruppe festlegen |
transition |
PageTransitionType |
Seitenuebergangstyp festlegen (veraltet, verwenden Sie transition_type) |
transition_settings |
PageTransitionSettings |
Uebergangseinstellungen festlegen |
Routen-Parameter verwenden
Wenn Sie eine neue Seite erstellen, koennen Sie die Route so aktualisieren, dass sie Parameter akzeptiert.
class ProfilePage extends NyStatefulWidget<HomeController> {
static RouteView path = ("/profile/{userId}", (_) => ProfilePage());
ProfilePage() : super(child: () => _ProfilePageState());
}
Wenn Sie nun zur Seite navigieren, koennen Sie die userId uebergeben
routeTo(ProfilePage.path.withParams({"userId": 7}));
Sie koennen auf die Parameter in der neuen Seite wie folgt zugreifen.
class _ProfilePageState extends NyPage<ProfilePage> {
@override
get init => () {
print(widget.queryParameters()); // {"userId": 7}
};
}
Query-Parameter
Beim Navigieren zu einer neuen Seite koennen Sie auch Query-Parameter angeben.
Schauen wir uns das an.
// 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}
};
Hinweis: Solange Ihr Seiten-Widget das
NyStatefulWidgetund dieNyPage-Klasse erweitert, koennen Siewidget.queryParameters()aufrufen, um alle Query-Parameter aus dem Routennamen abzurufen.
// 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"}
};
Tipp: Query-Parameter muessen dem HTTP-Protokoll folgen, z.B. /account?userId=1&tab=2
Seitenuebergaenge
Sie koennen Uebergaenge hinzufuegen, wenn Sie von einer Seite navigieren, indem Sie Ihre router.dart-Datei aendern.
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()
);
});
Verfuegbare Seitenuebergaenge
Grundlegende Uebergaenge
TransitionType.fade()- Blendet die neue Seite ein, waehrend die alte Seite ausgeblendet wirdTransitionType.theme()- Verwendet das Seitenuebergangs-Theme der App
Richtungsgebundene Slide-Uebergaenge
TransitionType.rightToLeft()- Gleitet vom rechten BildschirmrandTransitionType.leftToRight()- Gleitet vom linken BildschirmrandTransitionType.topToBottom()- Gleitet vom oberen BildschirmrandTransitionType.bottomToTop()- Gleitet vom unteren Bildschirmrand
Slide mit Fade-Uebergaenge
TransitionType.rightToLeftWithFade()- Gleitet und blendet vom rechten RandTransitionType.leftToRightWithFade()- Gleitet und blendet vom linken Rand
Transform-Uebergaenge
TransitionType.scale(alignment: ...)- Skaliert vom angegebenen AusrichtungspunktTransitionType.rotate(alignment: ...)- Rotiert um den angegebenen AusrichtungspunktTransitionType.size(alignment: ...)- Waechst vom angegebenen Ausrichtungspunkt
Verbundene Uebergaenge (erfordern aktuelles Widget)
TransitionType.leftToRightJoined(childCurrent: ...)- Aktuelle Seite geht nach rechts ab, waehrend neue Seite von links kommtTransitionType.rightToLeftJoined(childCurrent: ...)- Aktuelle Seite geht nach links ab, waehrend neue Seite von rechts kommtTransitionType.topToBottomJoined(childCurrent: ...)- Aktuelle Seite geht nach unten ab, waehrend neue Seite von oben kommtTransitionType.bottomToTopJoined(childCurrent: ...)- Aktuelle Seite geht nach oben ab, waehrend neue Seite von unten kommt
Pop-Uebergaenge (erfordern aktuelles Widget)
TransitionType.leftToRightPop(childCurrent: ...)- Aktuelle Seite geht nach rechts ab, neue Seite bleibt stehenTransitionType.rightToLeftPop(childCurrent: ...)- Aktuelle Seite geht nach links ab, neue Seite bleibt stehenTransitionType.topToBottomPop(childCurrent: ...)- Aktuelle Seite geht nach unten ab, neue Seite bleibt stehenTransitionType.bottomToTopPop(childCurrent: ...)- Aktuelle Seite geht nach oben ab, neue Seite bleibt stehen
Material Design Shared Axis-Uebergaenge
TransitionType.sharedAxisHorizontal()- Horizontaler Slide- und Fade-UebergangTransitionType.sharedAxisVertical()- Vertikaler Slide- und Fade-UebergangTransitionType.sharedAxisScale()- Skalierungs- und Fade-Uebergang
Anpassungsparameter
Jeder Uebergang akzeptiert die folgenden optionalen Parameter:
| Parameter | Beschreibung | Standard |
|---|---|---|
curve |
Animationskurve | Plattformspezifische Kurven |
duration |
Animationsdauer | Plattformspezifische Dauern |
reverseDuration |
Umgekehrte Animationsdauer | Gleich wie duration |
fullscreenDialog |
Ob die Route ein Vollbilddialog ist | false |
opaque |
Ob die Route undurchsichtig ist | false |
// Home page widget
class _HomePageState extends NyPage<HomePage> {
_showProfile() {
routeTo(ProfilePage.path,
transitionType: TransitionType.bottomToTop()
);
}
...
Navigationstypen
Beim Navigieren koennen Sie einen der folgenden Typen angeben, wenn Sie den routeTo-Helfer verwenden.
| Typ | Beschreibung |
|---|---|
NavigationType.push |
Eine neue Seite auf den Routen-Stack Ihrer App legen |
NavigationType.pushReplace |
Die aktuelle Route ersetzen, wobei die vorherige Route verworfen wird, sobald die neue Route beendet ist |
NavigationType.popAndPushNamed |
Die aktuelle Route vom Navigator entfernen und eine benannte Route an ihre Stelle setzen |
NavigationType.pushAndRemoveUntil |
Pushen und Routen entfernen, bis das Praedikat true zurueckgibt |
NavigationType.pushAndForgetAll |
Zu einer neuen Seite navigieren und alle anderen Seiten auf dem Routen-Stack verwerfen |
// Home page widget
class _HomePageState extends NyPage<HomePage> {
_showProfile() {
routeTo(
ProfilePage.path,
navigationType: NavigationType.pushReplace
);
}
...
Zurueck navigieren
Sobald Sie auf der neuen Seite sind, koennen Sie den pop()-Helfer verwenden, um zur vorherigen Seite zurueckzukehren.
// SettingsPage Widget
class _SettingsPageState extends NyPage<SettingsPage> {
_back() {
pop();
// or
Navigator.pop(context);
}
...
Wenn Sie einen Wert an das vorherige Widget zurueckgeben moechten, uebergeben Sie ein result wie im folgenden Beispiel.
// 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"}
});
}
...
Bedingte Navigation
Verwenden Sie routeIf(), um nur zu navigieren, wenn eine Bedingung erfuellt ist:
// 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,
);
Wenn die Bedingung false ist, findet keine Navigation statt.
Routen-Verlauf
In Nylo Website koennen Sie mit den folgenden Helfern auf die Routen-Verlaufsinformationen zugreifen.
// 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
Routen-Stack aktualisieren
Sie koennen den Navigationsstapel programmatisch mit NyNavigator.updateStack() aktualisieren:
// 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 | Typ | Standard | Beschreibung |
|---|---|---|---|
routes |
List<String> |
erforderlich | Liste der Routenpfade, zu denen navigiert werden soll |
replace |
bool |
true |
Ob der aktuelle Stack ersetzt werden soll |
dataForRoute |
Map<String, dynamic>? |
null |
Daten, die an bestimmte Routen uebergeben werden sollen |
Dies ist nuetzlich fuer:
- Deep-Linking-Szenarien
- Wiederherstellung des Navigationszustands
- Aufbau komplexer Navigationsablaeufe
Deep Linking
Deep Linking ermoeglicht es Benutzern, direkt zu bestimmten Inhalten in Ihrer App ueber URLs zu navigieren. Dies ist nuetzlich fuer:
- Teilen direkter Links zu bestimmten App-Inhalten
- Marketingkampagnen, die auf bestimmte In-App-Funktionen abzielen
- Behandlung von Benachrichtigungen, die bestimmte App-Bildschirme oeffnen sollen
- Nahtlose Web-zu-App-Uebergaenge
Einrichtung
Bevor Sie Deep Linking in Ihrer App implementieren, stellen Sie sicher, dass Ihr Projekt richtig konfiguriert ist:
1. Plattformkonfiguration
iOS: Konfigurieren Sie Universal Links in Ihrem Xcode-Projekt
Android: Richten Sie App Links in Ihrer AndroidManifest.xml ein
2. Definieren Sie Ihre Routen
Alle Routen, die ueber Deep Links erreichbar sein sollen, muessen in Ihrer Router-Konfiguration registriert sein:
// 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);
});
Deep Links verwenden
Sobald konfiguriert, kann Ihre App eingehende URLs in verschiedenen Formaten verarbeiten:
Grundlegende Deep Links
Einfache Navigation zu bestimmten Seiten:
https://yourdomain.com/profile // Opens the profile page
https://yourdomain.com/settings // Opens the settings page
Um diese Navigationen programmatisch in Ihrer App auszuloesen:
routeTo(ProfilePage.path);
routeTo(SettingsPage.path);
Pfad-Parameter
Fuer Routen, die dynamische Daten als Teil des Pfades erfordern:
Routendefinition
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
}
URL-Format
https://yourdomain.com/hotel/87/booking
Programmatische Navigation
// Navigate with parameters
routeTo(HotelBookingPage.path.withParams({"id": "87"}), queryParameters: {
"bookings": "active",
});
Query-Parameter
Fuer optionale Parameter oder wenn mehrere dynamische Werte benoetigt werden:
URL-Format
https://yourdomain.com/profile?user=20&tab=posts
https://yourdomain.com/hotel/87/booking?checkIn=2025-04-10&nights=3
Auf Query-Parameter zugreifen
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"}
};
}
Programmatische Navigation mit Query-Parametern
// 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",
});
Deep Links behandeln
Sie koennen Deep-Link-Events in Ihrem RouteProvider behandeln:
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();
}
}
Deep Links testen
Fuer Entwicklung und Tests koennen Sie die Deep-Link-Aktivierung mit ADB (Android) oder xcrun (iOS) simulieren:
# 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"
Debugging-Tipps
- Geben Sie alle Parameter in Ihrer Init-Methode aus, um die korrekte Analyse zu ueberpruefen
- Testen Sie verschiedene URL-Formate, um sicherzustellen, dass Ihre App sie korrekt behandelt
- Denken Sie daran, dass Query-Parameter immer als Strings empfangen werden - konvertieren Sie sie bei Bedarf in den entsprechenden Typ
Gaengige Muster
Parametertypkonvertierung
Da alle URL-Parameter als Strings uebergeben werden, muessen Sie sie oft konvertieren:
// 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"] ?? "");
Optionale Parameter
Behandeln Sie Faelle, in denen Parameter fehlen koennten:
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
}
Erweitert
Pruefen, ob eine Route existiert
Sie koennen pruefen, ob eine Route in Ihrem Router registriert ist:
if (Nylo.containsRoute("/profile")) {
routeTo("/profile");
}
NyRouter-Methoden
Die Klasse NyRouter bietet mehrere nuetzliche Methoden:
| Methode | Beschreibung |
|---|---|
getRegisteredRouteNames() |
Alle registrierten Routennamen als Liste abrufen |
getRegisteredRoutes() |
Alle registrierten Routen als Map abrufen |
containsRoutes(routes) |
Pruefen, ob der Router alle angegebenen Routen enthaelt |
getInitialRouteName() |
Den initialen Routennamen abrufen |
getAuthRouteName() |
Den authentifizierten Routennamen abrufen |
getUnknownRouteName() |
Den unbekannten/404-Routennamen abrufen |
Routen-Argumente abrufen
Sie koennen Routen-Argumente mit NyRouter.args<T>() abrufen:
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 und NyQueryParameters
Zwischen Routen uebergebene Daten werden in diesen Klassen verpackt:
// 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'}