Routeur
Introduction
Les routes vous permettent de definir les differentes pages de votre application et de naviguer entre elles.
Utilisez les routes lorsque vous avez besoin de :
- Definir les pages disponibles dans votre application
- Naviguer les utilisateurs entre les ecrans
- Proteger des pages derriere une authentification
- Passer des donnees d'une page a une autre
- Gerer les liens profonds a partir d'URLs
Vous pouvez ajouter des routes dans le fichier 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);
});
Astuce : Vous pouvez creer vos routes manuellement ou utiliser l'outil CLI Metro pour les creer pour vous.
Voici un exemple de creation d'une page 'account' avec Metro.
metro make:page account_page
// Adds your new route automatically to /lib/routes/router.dart
appRouter() => nyRoutes((router) {
...
router.add(AccountPage.path);
});
Vous pouvez aussi avoir besoin de passer des donnees d'une vue a une autre. Dans Nylo Website, c'est possible en utilisant le NyStatefulWidget (un widget avec etat integrant l'acces aux donnees de route). Nous approfondirons cela pour expliquer comment cela fonctionne.
Ajouter des routes
C'est la maniere la plus simple d'ajouter de nouvelles routes a votre projet.
Executez la commande ci-dessous pour creer une nouvelle page.
metro make:page profile_page
Apres l'execution de la commande ci-dessus, un nouveau Widget nomme ProfilePage sera cree et ajoute a votre repertoire resources/pages/.
Il ajoutera egalement la nouvelle route a votre fichier lib/routes/router.dart.
Fichier : /lib/routes/router.dart
appRouter() => nyRoutes((router) {
...
router.add(HomePage.path).initialRoute();
// My new route
router.add(ProfilePage.path);
});
Naviguer vers des pages
Vous pouvez naviguer vers de nouvelles pages en utilisant le helper routeTo.
void _pressedSettings() {
routeTo(SettingsPage.path);
}
Route initiale
Dans vos routeurs, vous pouvez definir la premiere page qui doit se charger en utilisant la methode .initialRoute().
Une fois que vous avez defini la route initiale, ce sera la premiere page chargee a l'ouverture de l'application.
appRouter() => nyRoutes((router) {
router.add(HomePage.path);
router.add(SettingsPage.path);
router.add(ProfilePage.path).initialRoute();
// new initial route
});
Route initiale conditionnelle
Vous pouvez egalement definir une route initiale conditionnelle en utilisant le parametre when :
appRouter() => nyRoutes((router) {
router.add(OnboardingPage.path).initialRoute(
when: () => !hasCompletedOnboarding()
);
router.add(HomePage.path).initialRoute(
when: () => hasCompletedOnboarding()
);
});
Naviguer vers la route initiale
Utilisez routeToInitial() pour naviguer vers la route initiale de l'application :
void _goHome() {
routeToInitial();
}
Cela naviguera vers la route marquee avec .initialRoute() et effacera la pile de navigation.
Route de previsualisation
Pendant le developpement, vous pouvez vouloir previsualiser rapidement une page specifique sans changer votre route initiale de maniere permanente. Utilisez .previewRoute() pour faire temporairement de n'importe quelle route la route initiale :
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(SettingsPage.path);
router.add(ProfilePage.path).previewRoute(); // This will be shown first during development
});
La methode previewRoute() :
- Remplace tout parametre
initialRoute()etauthenticatedRoute()existant - Fait de la route specifiee la route initiale
- Utile pour tester rapidement des pages specifiques pendant le developpement
Attention : N'oubliez pas de supprimer
.previewRoute()avant de publier votre application !
Route authentifiee
Dans votre application, vous pouvez definir une route comme route initiale lorsqu'un utilisateur est authentifie. Cela remplacera automatiquement la route initiale par defaut et sera la premiere page que l'utilisateur verra lorsqu'il se connectera.
Tout d'abord, votre utilisateur doit etre connecte en utilisant le helper Auth.authenticate({...}).
Maintenant, lorsqu'il ouvre l'application, la route que vous avez definie sera la page par defaut jusqu'a sa deconnexion.
appRouter() => nyRoutes((router) {
router.add(IntroPage.path).initialRoute();
router.add(LoginPage.path);
router.add(ProfilePage.path).authenticatedRoute();
// auth page
});
Route authentifiee conditionnelle
Vous pouvez egalement definir une route authentifiee conditionnelle :
router.add(ProfilePage.path).authenticatedRoute(
when: () => hasCompletedSetup()
);
Naviguer vers la route authentifiee
Vous pouvez naviguer vers la page authentifiee en utilisant le helper routeToAuthenticatedRoute() :
routeToAuthenticatedRoute();
Voir aussi : Authentification pour les details sur l'authentification des utilisateurs et la gestion des sessions.
Route inconnue
Vous pouvez definir une route pour gerer les scenarios 404/page non trouvee en utilisant .unknownRoute() :
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(NotFoundPage.path).unknownRoute();
});
Lorsqu'un utilisateur navigue vers une route qui n'existe pas, la page de route inconnue sera affichee.
Gardes de route
Les gardes de route protegent les pages contre les acces non autorises. Elles s'executent avant que la navigation ne se termine, vous permettant de rediriger les utilisateurs ou de bloquer l'acces selon des conditions.
Utilisez les gardes de route lorsque vous avez besoin de :
- Proteger des pages contre les utilisateurs non authentifies
- Verifier les permissions avant d'autoriser l'acces
- Rediriger les utilisateurs selon des conditions (ex. onboarding non termine)
- Enregistrer ou suivre les vues de pages
Pour creer une nouvelle garde de route, executez la commande ci-dessous.
metro make:route_guard dashboard
Ensuite, ajoutez la nouvelle garde de route a votre route.
// 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
});
Vous pouvez egalement definir des gardes de route en utilisant la methode 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()]);
})
Cycle de vie NyRouteGuard
Dans la v7, les gardes de route utilisent la classe NyRouteGuard avec trois methodes de cycle de vie :
onBefore(RouteContext context)- Appelee avant la navigation. Retourneznext()pour continuer,redirect()pour aller ailleurs, ouabort()pour arreter.onAfter(RouteContext context)- Appelee apres une navigation reussie vers la route.
Exemple de base
Fichier : /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
La classe RouteContext donne acces aux informations de navigation :
| Propriete | Type | Description |
|---|---|---|
context |
BuildContext? |
Le contexte de construction actuel |
data |
dynamic |
Les donnees passees a la route |
queryParameters |
Map<String, String> |
Les parametres de requete URL |
routeName |
String |
Le nom/chemin de la route |
originalRouteName |
String? |
Le nom original de la route avant les transformations |
@override
Future<GuardResult> onBefore(RouteContext context) async {
print('Navigating to: ${context.routeName}');
print('Query params: ${context.queryParameters}');
print('Route data: ${context.data}');
return next();
}
Methodes d'aide des gardes
next()
Continuer vers la garde suivante ou vers la route :
@override
Future<GuardResult> onBefore(RouteContext context) async {
return next(); // Allow navigation to continue
}
redirect()
Rediriger vers une route differente :
@override
Future<GuardResult> onBefore(RouteContext context) async {
if (!isLoggedIn) {
return redirect(
LoginPage.path,
data: {'returnTo': context.routeName},
navigationType: NavigationType.pushReplace,
);
}
return next();
}
La methode redirect() accepte :
| Parametre | Type | Description |
|---|---|---|
path |
Object |
Chemin de la route ou RouteView |
data |
dynamic |
Donnees a passer a la route |
queryParameters |
Map<String, dynamic>? |
Parametres de requete |
navigationType |
NavigationType |
Type de navigation (par defaut : pushReplace) |
transitionType |
TransitionType? |
Transition de page |
onPop |
Function(dynamic)? |
Callback lorsque la route est depilee |
abort()
Arreter la navigation sans rediriger :
@override
Future<GuardResult> onBefore(RouteContext context) async {
if (isMaintenanceMode) {
showMaintenanceDialog();
return abort(); // User stays on current route
}
return next();
}
setData()
Modifier les donnees passees aux gardes suivantes et a la route :
@override
Future<GuardResult> onBefore(RouteContext context) async {
final user = await fetchUser();
setData({'user': user, ...?context.data});
return next();
}
Gardes parameterises
Utilisez ParameterizedGuard lorsque vous devez configurer le comportement de la garde par route :
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'])
]);
Piles de gardes
Composez plusieurs gardes en une seule garde reutilisable en utilisant GuardStack :
// Create reusable guard combinations
final adminGuards = GuardStack([
AuthGuard(),
RoleGuard(['admin']),
AuditLogGuard(),
]);
router.add(AdminPage.path, routeGuards: [adminGuards]);
Gardes conditionnels
Appliquez des gardes conditionnellement en fonction d'un predicat :
router.add(DashboardPage.path, routeGuards: [
ConditionalGuard(
condition: (context) => context.routeName.startsWith('/admin'),
guard: AdminGuard(),
)
]);
Passer des donnees a une autre page
Dans cette section, nous montrerons comment vous pouvez passer des donnees d'un widget a un autre.
Depuis votre Widget, utilisez le helper routeTo et passez les data que vous souhaitez envoyer a la nouvelle page.
// 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
};
Plus d'exemples
// 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
};
Groupes de routes
Les groupes de routes organisent les routes liees et appliquent des parametres partages. Ils sont utiles lorsque plusieurs routes necessitent les memes gardes, prefixe d'URL ou style de transition.
Utilisez les groupes de routes lorsque vous avez besoin de :
- Appliquer la meme garde de route a plusieurs pages
- Ajouter un prefixe d'URL a un ensemble de routes (ex.
/admin/...) - Definir la meme transition de page pour des routes liees
Vous pouvez definir un groupe de routes comme dans l'exemple ci-dessous.
appRouter() => nyRoutes((router) {
...
router.group(() => {
"route_guards": [AuthRouteGuard()],
"prefix": "/dashboard",
"transition_type": TransitionType.fade(),
}, (router) {
router.add(ChatPage.path);
router.add(FollowersPage.path);
});
Options disponibles pour les groupes de routes :
| Option | Type | Description |
|---|---|---|
route_guards |
List<RouteGuard> |
Appliquer des gardes de route a toutes les routes du groupe |
prefix |
String |
Ajouter un prefixe a tous les chemins de route du groupe |
transition_type |
TransitionType |
Definir la transition pour toutes les routes du groupe |
transition |
PageTransitionType |
Definir le type de transition de page (obsolete, utilisez transition_type) |
transition_settings |
PageTransitionSettings |
Definir les parametres de transition |
Utiliser les parametres de route
Lorsque vous creez une nouvelle page, vous pouvez mettre a jour la route pour accepter des parametres.
class ProfilePage extends NyStatefulWidget<HomeController> {
static RouteView path = ("/profile/{userId}", (_) => ProfilePage());
ProfilePage() : super(child: () => _ProfilePageState());
}
Maintenant, lorsque vous naviguez vers la page, vous pouvez passer le userId
routeTo(ProfilePage.path.withParams({"userId": 7}));
Vous pouvez acceder aux parametres dans la nouvelle page comme ceci.
class _ProfilePageState extends NyPage<ProfilePage> {
@override
get init => () {
print(widget.queryParameters()); // {"userId": 7}
};
}
Parametres de requete
Lors de la navigation vers une nouvelle page, vous pouvez egalement fournir des parametres de requete.
Voyons cela.
// 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}
};
Note : Tant que votre widget de page etend
NyStatefulWidgetet la classeNyPage, vous pouvez appelerwidget.queryParameters()pour recuperer tous les parametres de requete du nom de la route.
// 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"}
};
Astuce : Les parametres de requete doivent suivre le protocole HTTP, par ex. /account?userId=1&tab=2
Transitions de page
Vous pouvez ajouter des transitions lorsque vous naviguez d'une page en modifiant votre fichier router.dart.
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()
);
});
Transitions de page disponibles
Transitions de base
TransitionType.fade()- Fait apparaitre la nouvelle page en fondu tout en faisant disparaitre l'ancienneTransitionType.theme()- Utilise le theme de transitions de page de l'application
Transitions directionnelles par glissement
TransitionType.rightToLeft()- Glisse depuis le bord droit de l'ecranTransitionType.leftToRight()- Glisse depuis le bord gauche de l'ecranTransitionType.topToBottom()- Glisse depuis le bord superieur de l'ecranTransitionType.bottomToTop()- Glisse depuis le bord inferieur de l'ecran
Transitions de glissement avec fondu
TransitionType.rightToLeftWithFade()- Glisse et apparait en fondu depuis le bord droitTransitionType.leftToRightWithFade()- Glisse et apparait en fondu depuis le bord gauche
Transitions de transformation
TransitionType.scale(alignment: ...)- Mise a l'echelle depuis un point d'alignement specifieTransitionType.rotate(alignment: ...)- Rotation autour d'un point d'alignement specifieTransitionType.size(alignment: ...)- Agrandit depuis un point d'alignement specifie
Transitions jointes (necessite le widget actuel)
TransitionType.leftToRightJoined(childCurrent: ...)- La page actuelle sort a droite tandis que la nouvelle entre par la gaucheTransitionType.rightToLeftJoined(childCurrent: ...)- La page actuelle sort a gauche tandis que la nouvelle entre par la droiteTransitionType.topToBottomJoined(childCurrent: ...)- La page actuelle sort vers le bas tandis que la nouvelle entre par le hautTransitionType.bottomToTopJoined(childCurrent: ...)- La page actuelle sort vers le haut tandis que la nouvelle entre par le bas
Transitions Pop (necessite le widget actuel)
TransitionType.leftToRightPop(childCurrent: ...)- La page actuelle sort a droite, la nouvelle reste en placeTransitionType.rightToLeftPop(childCurrent: ...)- La page actuelle sort a gauche, la nouvelle reste en placeTransitionType.topToBottomPop(childCurrent: ...)- La page actuelle sort vers le bas, la nouvelle reste en placeTransitionType.bottomToTopPop(childCurrent: ...)- La page actuelle sort vers le haut, la nouvelle reste en place
Transitions Material Design a axe partage
TransitionType.sharedAxisHorizontal()- Transition de glissement horizontal et fonduTransitionType.sharedAxisVertical()- Transition de glissement vertical et fonduTransitionType.sharedAxisScale()- Transition de mise a l'echelle et fondu
Parametres de personnalisation
Chaque transition accepte les parametres optionnels suivants :
| Parametre | Description | Defaut |
|---|---|---|
curve |
Courbe d'animation | Courbes specifiques a la plateforme |
duration |
Duree de l'animation | Durees specifiques a la plateforme |
reverseDuration |
Duree de l'animation inverse | Identique a la duree |
fullscreenDialog |
Si la route est un dialogue plein ecran | false |
opaque |
Si la route est opaque | false |
// Home page widget
class _HomePageState extends NyPage<HomePage> {
_showProfile() {
routeTo(ProfilePage.path,
transitionType: TransitionType.bottomToTop()
);
}
...
Types de navigation
Lors de la navigation, vous pouvez specifier l'un des types suivants si vous utilisez le helper routeTo.
| Type | Description |
|---|---|
NavigationType.push |
Empiler une nouvelle page sur la pile de routes de votre application |
NavigationType.pushReplace |
Remplacer la route actuelle, en supprimant la route precedente une fois que la nouvelle est terminee |
NavigationType.popAndPushNamed |
Depiler la route actuelle du navigateur et empiler une route nommee a sa place |
NavigationType.pushAndRemoveUntil |
Empiler et supprimer les routes jusqu'a ce que le predicat retourne true |
NavigationType.pushAndForgetAll |
Naviguer vers une nouvelle page et supprimer toutes les autres pages de la pile de routes |
// Home page widget
class _HomePageState extends NyPage<HomePage> {
_showProfile() {
routeTo(
ProfilePage.path,
navigationType: NavigationType.pushReplace
);
}
...
Naviguer en arriere
Une fois sur la nouvelle page, vous pouvez utiliser le helper pop() pour revenir a la page existante.
// SettingsPage Widget
class _SettingsPageState extends NyPage<SettingsPage> {
_back() {
pop();
// or
Navigator.pop(context);
}
...
Si vous souhaitez retourner une valeur au widget precedent, fournissez un result comme dans l'exemple ci-dessous.
// 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"}
});
}
...
Navigation conditionnelle
Utilisez routeIf() pour naviguer uniquement lorsqu'une condition est remplie :
// 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,
);
Si la condition est false, aucune navigation ne se produit.
Historique des routes
Dans Nylo Website, vous pouvez acceder aux informations de l'historique des routes en utilisant les helpers ci-dessous.
// 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
Mettre a jour la pile de routes
Vous pouvez mettre a jour la pile de navigation par programmation en utilisant 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}
}
);
| Parametre | Type | Defaut | Description |
|---|---|---|---|
routes |
List<String> |
requis | Liste des chemins de route vers lesquels naviguer |
replace |
bool |
true |
Indique s'il faut remplacer la pile actuelle |
dataForRoute |
Map<String, dynamic>? |
null |
Donnees a passer a des routes specifiques |
C'est utile pour :
- Les scenarios de liens profonds
- La restauration de l'etat de navigation
- La construction de flux de navigation complexes
Liens profonds
Les liens profonds permettent aux utilisateurs de naviguer directement vers un contenu specifique dans votre application en utilisant des URLs. C'est utile pour :
- Partager des liens directs vers un contenu specifique de l'application
- Les campagnes marketing ciblant des fonctionnalites specifiques de l'application
- Gerer les notifications qui doivent ouvrir des ecrans specifiques
- Les transitions transparentes du web vers l'application
Configuration
Avant d'implementer les liens profonds dans votre application, assurez-vous que votre projet est correctement configure :
1. Configuration de la plateforme
iOS : Configurez les liens universels dans votre projet Xcode
Android : Configurez les liens d'application dans votre AndroidManifest.xml
2. Definir vos routes
Toutes les routes qui doivent etre accessibles via les liens profonds doivent etre enregistrees dans la configuration de votre routeur :
// 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);
});
Utiliser les liens profonds
Une fois configure, votre application peut gerer les URLs entrantes dans differents formats :
Liens profonds de base
Navigation simple vers des pages specifiques :
https://yourdomain.com/profile // Opens the profile page
https://yourdomain.com/settings // Opens the settings page
Pour declencher ces navigations par programmation dans votre application :
routeTo(ProfilePage.path);
routeTo(SettingsPage.path);
Parametres de chemin
Pour les routes qui necessitent des donnees dynamiques dans le chemin :
Definition de la route
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 d'URL
https://yourdomain.com/hotel/87/booking
Navigation programmatique
// Navigate with parameters
routeTo(HotelBookingPage.path.withParams({"id": "87"}), queryParameters: {
"bookings": "active",
});
Parametres de requete
Pour les parametres optionnels ou lorsque plusieurs valeurs dynamiques sont necessaires :
Format d'URL
https://yourdomain.com/profile?user=20&tab=posts
https://yourdomain.com/hotel/87/booking?checkIn=2025-04-10&nights=3
Acceder aux parametres de requete
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"}
};
}
Navigation programmatique avec parametres de requete
// 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",
});
Gerer les liens profonds
Vous pouvez gerer les evenements de liens profonds dans votre RouteProvider :
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();
}
}
Tester les liens profonds
Pour le developpement et les tests, vous pouvez simuler l'activation des liens profonds en utilisant ADB (Android) ou 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"
Conseils de debogage
- Affichez tous les parametres dans votre methode init pour verifier l'analyse correcte
- Testez differents formats d'URL pour vous assurer que votre application les gere correctement
- N'oubliez pas que les parametres de requete sont toujours recus sous forme de strings, convertissez-les au type approprie si necessaire
Patterns courants
Conversion de type des parametres
Comme tous les parametres d'URL sont passes sous forme de strings, vous devrez souvent les convertir :
// 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"] ?? "");
Parametres optionnels
Gerez les cas ou les parametres peuvent etre manquants :
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
}
Avance
Verifier si une route existe
Vous pouvez verifier si une route est enregistree dans votre routeur :
if (Nylo.containsRoute("/profile")) {
routeTo("/profile");
}
Methodes NyRouter
La classe NyRouter fournit plusieurs methodes utiles :
| Methode | Description |
|---|---|
getRegisteredRouteNames() |
Obtenir tous les noms de routes enregistrees sous forme de liste |
getRegisteredRoutes() |
Obtenir toutes les routes enregistrees sous forme de map |
containsRoutes(routes) |
Verifier si le routeur contient toutes les routes specifiees |
getInitialRouteName() |
Obtenir le nom de la route initiale |
getAuthRouteName() |
Obtenir le nom de la route authentifiee |
getUnknownRouteName() |
Obtenir le nom de la route inconnue/404 |
Obtenir les arguments de route
Vous pouvez obtenir les arguments de route en utilisant 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 et NyQueryParameters
Les donnees passees entre les routes sont encapsulees dans ces classes :
// 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'}