Доступ к нескольким полям из Selector (при использовании управления состоянием провайдера во Flutter)? - PullRequest
1 голос
/ 14 января 2020

У меня есть приложение диспетчера задач, которое отображает несколько виджетов TaskWidget в ListView, и в настоящее время я пытаюсь изменить свое приложение, чтобы использовать Provider для управления состоянием. У меня есть класс TaskListModel в качестве моего ChangeNotifier, который содержит список TaskModel вместе с некоторыми методами получения и установки, которые вызывают notifyListeners (). (TaskModel не является ChangeNotifier) ​​

Когда пользователь изменяет данные для одной задачи в списке, я хочу перестроить этот виджет без перестройки всех других виджетов в списке. Селектор почти делает то, что я хочу, за исключением того, что мне нужен доступ ко всем полям в TaskModel, чтобы перестроить соответствующий TaskWidget, тогда как Selector, кажется, работает только с одним полем. Я попытался использовать Selector, установив селектор для экземпляра TaskModel, используя индекс списка. Я предполагаю, что это не работает, потому что он слушает ссылку на TaskModel (которая не изменяется), а не на все поля в TaskModel. Есть ли прямой способ для меня сделать это? Я включил метод сборки для TaskWidget ниже для справки.

  Widget build(BuildContext context) {
return Column(children: <Widget>[
  Selector<TaskListModel, TaskModel>(
    selector: (_, taskListModel) => taskListModel.taskList[index],
    builder: (_, taskModel, child) {
      print("rebuilding " + index.toString());

      return Material(
        color: taskModel.color,
        child: ListTile(
          title: Column(children: <Widget>[
            Text(
              taskModel.name,
              style: _taskFont,
              textAlign: TextAlign.center,
            ),
            Text(
              taskModel.formattedTime,
              style: _taskFont,
              textAlign: TextAlign.center,
            ),
          ]),
        ),
      );
    },
  ),
  Divider(
    height: 0.0,
  ),
]);

  }

1 Ответ

2 голосов
/ 14 января 2020

Как указано в документации Selector , вы должны либо создать собственный класс, либо использовать пакет tuple.

Чтобы выбрать несколько значений без необходимости записывать класс, который реализует ==, самое простое решение - использовать «кортеж» из кортежа:

Selector<Foo, Tuple2<Bar, Baz>>(
  selector: (_, foo) => Tuple2(foo.bar, foo.baz),
  builder: (_, data, __) {
    return Text('${data.item1}  ${data.item2}');
  }
)

...