我目前正在尝试使用 BloC 构建一个 Flutter 应用程序,遇到了一些问题,希望你们能帮助我!总的来说,我是 BloC 的新手,所以请理解。
我创建了一个 BloC,用于从 firestore 添加、删除、更新和列出数据,效果很好。我需要一些帮助是为了使我的代码查询仅在我使用获得的pickDate变量在我的日历小部件中选择的同一天创建的条目。
我希望 ListView 生成正确日期的任务,例如,如果 2020-05-19 有 2 个任务,则在日历中选择这一天时应该出现两个任务。我真的不知道我需要更改或在日历上做什么才能实现这一目标,因为我仍然认为 BloC 有点令人困惑。
我是否必须为日历制作一个单独的块,还是可以使用处理我的任务的同一个块?
也许这只是我忘记做的一件小事,但此刻我感到完全迷失了。目前,我将所有 firestore 条目提取到 ListView 中,以查看它是否有效,如下所示:
Widget _buildCalendarListView(BuildContext context) {
return BlocBuilder<TasksBloc, TasksState>(builder: (context, state) {
if (state is TasksLoading) {
return CircularProgressIndicator();
}
if (state is TasksLoaded) {
return Expanded(
child: ListView.builder(
itemCount: state.tasks.length,
itemBuilder: (context, index) {
var task = state.tasks[index];
return ListTile(
title: Text(task.description),
);
},
),
);
} else {
return Text('No tasks');
}
});
}
这是我的日历小部件:
Widget _buildTableCalendar() {
return TableCalendar(
onDaySelected: (DateTime day, List events) {
pickedDate = day;
},
calendarController: _calendarController,
startingDayOfWeek: StartingDayOfWeek.monday,
calendarStyle: CalendarStyle(
selectedColor: Colors.blue,
todayColor: Colors.blue[200],
),
);
}
和我现在通过日期时间的任务的 BloC:
class TasksBloc extends Bloc<TasksEvent, TasksState> {
final TaskRepository _taskRepository;
StreamSubscription _taskSubscription;
TasksBloc({@required TaskRepository taskRepository})
: assert(taskRepository != null),
_taskRepository = taskRepository;
@override
TasksState get initialState => TasksLoading();
@override
Stream<TasksState> mapEventToState(
TasksEvent event,
) async* {
if (event is LoadTasks) {
yield* _mapLoadTasksToState(DateTime.now());
} else if (event is AddTask) {
yield* _mapAddTaskToState(event);
} else if (event is UpdateTask) {
yield* _mapUpdateTaskToState(event);
} else if (event is DeleteTask) {
yield* _mapDeleteTaskToState(event);
} else if (event is TasksUpdated) {
yield* _mapTaskUpdatedToState(event);
}
}
Stream<TasksState> _mapLoadTasksToState(DateTime queryDate) async* {
_taskSubscription?.cancel();
_taskSubscription = _taskRepository.tasks(DateTime.now()).listen((tasks) {
add(
TasksUpdated(tasks),
);
});
}
Stream<TasksState> _mapAddTaskToState(AddTask event) async* {
_taskRepository.addTask(event.task);
}
Stream<TasksState> _mapUpdateTaskToState(UpdateTask event) async* {
_taskRepository.updateTask(event.updatedTask);
}
Stream<TasksState> _mapDeleteTaskToState(DeleteTask event) async* {
_taskRepository.deleteTask(event.task);
}
Stream<TasksState> _mapTaskUpdatedToState(TasksUpdated event) async* {
yield TasksLoaded(event.tasks);
}
}
这是我为 firestore 创建的存储库:
class FirebaseTaskRepository extends TaskRepository {
final taskCollection = Firestore.instance.collection('tasks');
@override
Future<void> addTask(Task task) {
return taskCollection.add(task.toEntity().toDocument());
}
@override
Future<void> deleteTask(Task task) {
return taskCollection.document(task.id).delete();
}
/* @override
Stream<List<Task>> tasks() {
return taskCollection.snapshots().map((snapshot) {
return snapshot.documents
.map((doc) => Task.fromEntity(TaskEntity.fromJson(doc.data)))
.toList();
});
} */
@override
Stream<List<Task>> tasks(DateTime queryDate) {
return taskCollection
.where('date', isGreaterThan: queryDate)
.snapshots()
.map((snapshot) {
return snapshot.documents
.map((doc) => Task.fromEntity(TaskEntity.fromJson(doc.data)))
.toList();
});
}
@override
Future<void> updateTask(Task update) {
return taskCollection
.document(update.id)
.updateData(update.toEntity().toDocument());
}
}
还有我的 Main.dart,我在哪里使用 MultiBlocProvider,我不确定我是否正确使用,因为我无法实现我想要的?:
void main() {
WidgetsFlutterBinding.ensureInitialized();
BlocSupervisor.delegate = MyBlocDelegate();
final UserRepository userRepository = UserRepository();
runApp(
BlocProvider(
create: (context) =>
AuthenticationBloc(userRepository: userRepository)..add(AppStarted()),
child: App(userRepository: userRepository),
),
);
}
class App extends StatelessWidget {
final UserRepository _userRepository;
App({Key key, @required UserRepository userRepository})
: assert(userRepository != null),
_userRepository = userRepository,
super(key: key);
/* @override
Widget build(BuildContext context) {
return MaterialApp(
home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state) {
if (state is Unauthenticated) {
return LoginScreen(userRepository: _userRepository);
}
if (state is Authenticated) {
return HomePage(name: state.displayName);
}
return SplashScreen();
},
),
);
} */
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<TasksBloc>(
create: (context) {
return TasksBloc(
taskRepository: FirebaseTaskRepository(),
)..add(LoadTasks());
},
)
],
child: MaterialApp(
routes: {
'/': (context) {
return BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state) {
if (state is Unauthenticated) {
return LoginScreen(userRepository: _userRepository);
}
if (state is Authenticated) {
return HomePage(name: state.displayName);
}
return SplashScreen();
},
);
},
'/addTask': (context) {
return NewTaskScreen(
onSave: (task, description, date) {
BlocProvider.of<TasksBloc>(context).add(
AddTask(
Task(task, description: description, date: date),
),
);
},
);
},
'/calendarScreen': (context) {
return CalendarScreen();
}
},
),
);
}
}