#dart #flutter #bloc
#дротик #флаттер #блок
Вопрос:
Я разрабатываю приложение flutter ‘todo’, используя шаблон блочной архитектуры.
Мой пользовательский интерфейс «Home» отображает список задач, и пользователь может нажать кнопку элемента, чтобы изменить статус с «todo» на «завершено».
Когда элемент завершен, он должен отображаться другим цветом, отличным от других незавершенных задач.
Но когда я нажимаю кнопку «Завершить», представление списка не обновляется.
Ниже приведен мой код пользовательского интерфейса:
class HomePage extends StatelessWidget {
final TodoRepository _todoRepository;
final HomeBloc bloc;
HomePage(this._todoRepository) : this.bloc = HomeBloc(_todoRepository);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: StreamBuilder<List<Task>>(
stream: bloc.todos,
builder: (context, snapshot) {
return ListView(
children: snapshot.data.map(_buildItem).toList(),
);
}),
),
);
}
Widget _buildItem(Todo todo) {
if (todo.complete) {
return completed(todo);
} else {
return inCompleted(todo);
}
}
Widget inCompleted(Todo todo) {
return MaterialButton(
textColor: Colors.white,
color: Colors.green,
child: Text("Complete"),
onPressed: () {
bloc.done.add(todo);
}
);
}
Widget completed(Todo todo) {
return MaterialButton(
textColor: Colors.white,
color: Colors.red,
child: Text("Cancel"),
onPressed: () {
bloc.done.add(todo);
}
);
}
}
И вот мой класс блока:
class HomeBloc {
final _getTodosSubject = PublishSubject<List<Todo>>();
final _doneTodoSubject = PublishSubject<Todo>();
final _cancelTodoSubject = PublishSubject<Todo>();
final TodoRepository _todoRepository;
var _todos = <Todo>[];
Stream<List<Todo>> get todos => _getTodosSubject.stream;
Sink<Todo> get done => _doneTodoSubject.sink;
Sink<Todo> get cancel => _doneTodoSubject.sink;
HomeBloc(this._todoRepository) {
_getTodos().then((_) {
_getTodosSubject.add(_todos);
});
_doneTodoSubject.listen(_doneTodo);
_cancelTodoSubject.listen(_cancelTodo);
}
Future<Null> _getTodos() async {
await _todoRepository.getAll().then((list) {
_todos = list;
});
}
void _doneTodo(Todo todo) {
todo.complete = true;
_update(todo);
}
void _cancelTodo(Todo todo) async {
todo.complete = false;
_update(todo);
}
void _update(Todo todo) async {
await _todoRepository.save(todo);
_getTodos();
}
}
Ответ №1:
Это потому, что вы не «обновляете» свой список после вызова getTodos()
вот изменение:
HomeBloc(this._todoRepository) {
_getTodos() //Remove the adding part it's done in the function
_doneTodoSubject.listen(_doneTodo);
_cancelTodoSubject.listen(_cancelTodo);
}
Future<Null> _getTodos() async {
await _todoRepository.getAll().then((list) {
_todos = list;
_getTodosSubject.add(list); //You can actually remove the buffer _todos object
});
}
Как я упоминал в комментарии, вы можете удалить _todos
буфер, но я не хочу сильно отвлекаться на ваш код.
С этими несколькими настройками это должно сработать. Надеюсь, это поможет!!
Комментарии:
1. Спасибо, это работает! _getTodosSubject.sink.add(список); тоже работает. Знаете ли вы, в чем различия между ними?