有点简化,我的应用程序路由具有三个嵌套级别:
/profile
/course
/quiz
这些由命名的路由/profile
,/profile/course
和/profile/course/quiz
表示。这些路由映射到小部件:ProfileScreen
,CourseScreen
和QuizScreen
。每个对象都有一个参数:Profile
,Course
和Quiz
模型对象。
[如果我理解正确,Navigator
将确保父路由始终在子路由之前位于堆栈上,所以当我们在/profile/course/quiz
路由上时,将在其上方具有/profile/course
。
现在,我在QuizScreen
小部件中,我想访问当前的Course
。我该怎么办?
[它在路由堆栈中的某个位置,但是ModalRoute.of(context)
当然会给我/profile/course/quiz
路由,而不是/profile/course
路由,因此ModalRoute.of(context).settings.arguments
将是Quiz
。
[我尝试将CourseScreen
包装在Provider<Course>
小部件中(来自出色的providers
包),该工具将Course
向下提供给子小部件,但是子路由实际上变成了兄弟小部件,而不是子小部件。
当然,我可以显式地将Course
传递给/profile/course/quiz
路由作为第二个参数(与Quiz
一起包装在数组或对象中),但这似乎不必要地令人费解并且无法很好地扩展。
是否可以获取父路由的路由参数?还是这实际上表明我做错了,应该设计不同的应用程序?
当然,我可以显式地将
Course
传递给/profile/course/quiz
路由作为第二个参数(与Quiz
一起包装在数组或对象中),但这似乎不必要地令人费解并且无法很好地扩展。
毕竟,我为这种方法找到了令人信服的论点:可测试性。这意味着可以独立于所有其他屏幕甚至是路由系统来测试QuizScreen
。
所以我创建了一个简单的类来保存参数:
class QuizScreenArgs {
final Course course;
final Quiz quiz;
QuizScreenArgs(this.course, this.quiz);
}
然后我意识到我可以更进一步,使每条路线成为一个班级:
class QuizRoute extends MaterialRoute<QuizResult> {
QuizRoute(Course course, Quiz quiz) : super
}
这具有路由参数和路由的返回类型都被显式键入的优点。不再有ModalRoute.of(context).settings.arguments as IHopeThisIsWhatWasPassed
或(await Navigator.of(...).pushNamed(...)) as IHopeThisIsWhatWasReturned
。
它必须是一个类(而不仅仅是工厂方法),因此我们可以使用Navigator.popUntil
:
Navigator.of(context).popUntil((route) => route is CourseRoute);
总而言之,我对这种方法感到非常满意,并且我很惊讶文档不推荐甚至暗示这种可能性。