【发布时间】:2020-06-28 14:01:41
【问题描述】:
我有Courses 和Tasks。每个Course 有很多Tasks。这就是为什么我在应用程序中使用不同的屏幕来显示课程列表,点击课程后,我将导航到下一个屏幕 - 任务列表。这是我的onTap 方法的课程列表:
onTap: () {
TasksPageLoadedEvent pageLoadedEvent =
TasksPageLoadedEvent(
courseId: state.courses[index].id,
truckNumber: this.truckNumber,
);
serviceLocator<TaskBloc>().add(pageLoadedEvent);
Routes.sailor(
Routes.taskScreen,
params: {
Routes.courseNumber:
state.courses[index].courseNumber,
Routes.truckNumber: this.truckNumber,
Routes.courseId: state.courses[index].id,
},
);
}
我创建了一个TasksPageLoadedEvent,将其传递给TaskBloc,然后导航到“任务”页面。
这里是TaskBloc 以及它如何处理映射事件 - 状态:
@override
Stream<TaskState> mapEventToState(
TaskEvent event,
) async* {
if (event is TasksLoadingEvent) {
yield TasksLoadingState();
} else if (event is TasksReloadingErrorEvent) {
yield TasksErrorState();
} else if (event is TasksFetchedFailureEvent) {
yield TaskFetchedStateFailureState(error: event.failure);
} else if (event is TasksPulledFromServerEvent) {
yield TasksPulledFromServerState(
truckNumber: event.truckNumber,
courseNumber: event.courseNumber,
courseId: event.courseId,
);
} else if (event is TasksPageLoadedEvent) {
yield TasksLoadingState();
final networkInfoEither = await this.getNetworkInfoQuery(NoQueryParams());
yield* networkInfoEither.fold((failure) async* {
yield TasksErrorState();
}, (success) async* {
if (success) {
final getTasksEither = await getTasksQuery(
GetTasksParams(
truckNumber: event.truckNumber,
courseId: event.courseId,
),
);
yield* getTasksEither.fold((failure) async* {
yield TaskFetchedStateFailureState(error: "coursesDatabaseError");
}, (result) async* {
if (result != null) {
yield TasksFetchedState(tasks: result);
} else {
yield TaskFetchedStateFailureState(
error: "coursesFetchFromDatabaseError");
}
});
} else {
yield TasksNoInternetState();
}
});
}
}
当我导航到“任务”页面时,BlocBuilder 会检查状态并相应地处理建筑物。我有一个返回功能,可以导航回课程页面:
onPressed: () {
serviceLocator<CourseBloc>().add(
CoursesPageLoadedEvent(truckNumber: this.truckNumber),
);
Navigator.of(context).pop(true);
},
这会触发上一页的类似事件并重新加载。
如果我想参加另一门课程并查看其任务,就会出现我面临的问题。如果我点击列表中的另一个项目并因此触发一个新的TasksPageLoadedEvent(具有新属性),则根本不会调用mapEventToState()。
我之前在 BLoC 上遇到过类似的问题,但它们是关于 BlocListener 和扩展 Equatable 的状态。这就是为什么我的事件没有扩展Equatable(尽管我不确定这是否是这里的问题)。但仍然没有任何反应。
这是我的活动:
abstract class TaskEvent {
const TaskEvent();
}
class TasksPageLoadedEvent extends TaskEvent {
final String truckNumber;
final int courseId;
TasksPageLoadedEvent({
this.truckNumber,
this.courseId,
});
}
class TasksFetchedFailureEvent extends TaskEvent {
final String failure;
TasksFetchedFailureEvent({
this.failure,
});
}
class TasksLoadingEvent extends TaskEvent {}
class TasksReloadingErrorEvent extends TaskEvent {}
class TasksPulledFromServerEvent extends TaskEvent {
final String courseNumber;
final String truckNumber;
final int courseId;
TasksPulledFromServerEvent({
@required this.courseNumber,
@required this.truckNumber,
@required this.courseId,
});
}
我应该如何使用每个页面的两个 BLoC 在两个页面之间来回处理?
【问题讨论】:
-
我建议你使用这个插件pub.dev/packages/flutter_bloc
-
但我是,这是我正在使用的插件。
-
它是否仍能正确导航到 TaskPage?如果是, blocbuilder
是否仍处于相同状态?你怎么知道 mapEventToState 根本没有被调用? -
嗨!我希望你能看到我的问题 :) 是的,它可以导航。我放了一个断点。 BlocBuilder
处于“返回上一页”操作之前的最后一个状态。 -
哈哈.. 别对我抱太大期望。我不确定,但我假设 serviceLocator 提供了一个 TaskBloc 实例。话虽如此,您如何实现 BlocBuilder,因为据我所知,您不使用 BlocProvider 来提供 TaskBloc 实例。也许发生的事情是它在从 TaskPage 导航回来后使用了不同的 TaskBloc 实例