我使用 Riverpod NotifierProvider 并将数据对象列表作为数据源。
class FooData {
final int data1;
final String data2;
final String data3;
FooData({this.data1 = 0, this.data2 = "", this.data3 = "",});
FooData copyWith({int? data1, String? data2, String? data3,}) {
return FooData(data1: data1 ?? this.data1, data2: data2 ?? this.data2, data3: data3 ?? this.data3);
}
final foodataListProvider = NotifierProvider<FooDataListNotifier, List<FooData>>(FooDataListNotifier.new);
class FooDataListNotifier extends Notifier<List<FooData>> {
void addFooData(FooData input) {
state = [...state, input];
}
void updateFooAt(int index, {int? data1, String? data2, String? data3}) {
//This is where I'm not sure what exactly what I need to do to update the state
//while maintaining the immutability for the list.
state[index].copyWith(
data1: data1 ?? state[index].data1,
data2: data2 ?? state[index].data2,
data3: data3 ?? state[index].data3,);
state = [...state];
}
}
addFooData 方法按预期工作,但我无法使用提供程序更新列表中的项目。
在我的 ConsumerWidget 中,我使用
final provider = ref.watch(foodataListProvider);
访问它
对于提供者,final notifier = ref.watch(foodataListProvider.notifier);
对于通知者。
然后在 ElevatedButton 的 onPressed 中我像这样访问它 notifier.updateFooAt(index, data1: "New Data");
我尝试过不同的 updateFooAt 实现,例如
FooData data = state[index];
data.copyWith(data1: data1);
state = [...state, data];
和
List<FooData> dataList = state;
dataList[index].copyWith(data1: data1);
state = [...dataList];
我还使用
ref.read(foodataListProvider.notifier).updateFooAt(index, data1: "New Data");
在 onPressed 中访问了它
当我调试时,我看到列表中添加了新的 FooData,但是当我尝试更新它们时,它们保留了 addFooData 中的数据,但它们不会更新。
我查看了这个解决方案,但它在数据对象内使用了一个列表。并不是说我反对这样做,而是我想弄清楚如何通过我的设置来做到这一点。其他一些问题给了我想法,但没有解决问题。
Notifier<List<SomeType>> is troublesome
。所有更新都必须伴有对 ref.notifyListeners()
的调用。这将解决您眼前的问题,但请考虑使用 IList
(快速不可变集合)或自定义列表持有者类来使其不可变。