我不知道为什么我的提供程序每次更新状态时都调用build。
本质上,我调用controller.createVoice
,然后应该创建一个带有id的语音,并将其附加到selectedIds
,但出于某种原因,它不是。我怀疑这与build被调用以及我实际上是如何构建东西有关。
class _EditTopicScreenState extends ConsumerState<EditTopicScreen> {
@override
Widget build(BuildContext context) {
final controller =
ref.read(editTopicControllerProvider(topicId: widget.topicId).notifier);
final state =
ref.watch(editTopicControllerProvider(topicId: widget.topicId));
final topicNameFieldController =
TextEditingController(text: controller.name);
return FlutterDataWidget<Topic?>(
findRequest: ref.topics.findOne(widget.topicId, remote: false),
child: (topic) {
return Drawer(
// ...
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
...
VoiceCreatorV2(
onAdd: (name) => controller.createVoice(name),
),
const SizedBox(height: 20),
Flexible(
child: VoicesSelectV2(
selectedVoiceIds: state.selectedIds,
onAdd: (voiceId) => controller.addVoice(voiceId),
onRemove: (voiceId) =>
controller.removeVoice(voiceId),
),
),
// ...
],
),
),
));
});
}
}
Riverpod代码在这里,我用的是2.0
@riverpod
class EditTopicController extends _$EditTopicController {
@override
EditTopicControllerState build({required String topicId}) {
final voices = ref.voices.watchAll(remote: false).model;
final activeVoices = voices?.where((v) => v.archivedAt == null).toList() ??
[]; // Used for sorting voices on load so the ones selected are first
final topic = ref.topics.watchOne(topicId, remote: false).model;
final selectedIds =
topic?.voices.toList().map((e) => e.id!).toList() ?? [] as List<String>;
final List<Voice> sortedVoices = [
...activeVoices.where((v) => selectedIds.contains(v.id)).toList(),
...activeVoices.where((v) => !selectedIds.contains(v.id)).toList()
]; // Used for sorting voices on load so the ones selected are first
return EditTopicControllerState(
name: topic?.name ?? '',
selectedIds: selectedIds,
sortedVoices: sortedVoices);
}
List<String> get selectedIds => state.selectedIds;
String get name => state.name;
void updateTopicName(String name) {
state = state.copyWith(name: name);
}
void addVoice(String id) {
state = state.copyWith(selectedIds: [...state.selectedIds, id]);
}
//...
void createVoice(String name) async {
// used voice model to create voice
final voice = await Voice.newVoice(
name: name,
color: HexColorParser().generateRandomHexColor(),
).save(remote: true);
addVoice(voice.id!);
}
//...
}
坦白地说,我不确定这是否是处理这样的事情的正确方法,也许我错过了一个关键的概念,所以如果我是,让我知道。
我希望这是所有需要得到帮助的!
先谢谢你了
1条答案
按热度按时间yr9zkbsy1#
这条线就是罪魁祸首
final voices = ref.voices.watchAll(remote: false).model;
好吧,原来问题出在供应商身上。我在观察所有的声音,因为我在观察它们,当我创造一个新的声音时,它完全重建,由于它被观察,从而消除了我的状态。