什么是颤振中模态小部件(基于提供者)状态管理的最佳实践,当用户进行编辑时,更改不会传播到父页面,直到用户确认/关闭模态小部件。可选地,用户可以选择放弃更改。
简而言之:
- 具有确定和取消操作的模态小部件,或
- 模态小部件在模态关闭时应用更改
目前,我的解决方案看起来像这样
- 创建当前状态的副本
- 调用颤振的 show___() 函数并使用提供者(使用 .value 构造函数)包装小部件以公开状态副本
- 如果需要,在模态小部件关闭时更新原始状态
案例 #2 的示例:
Future<void> showEditDialog() async {
// Create a copy of the current state
final orgState = context.read<MeState>();
final tmpState = MeState.from(orgState);
// show modal widget with new provider
await showDialog<void>(
context: context,
builder: (_) => ChangeNotifierProvider<MeState>.value(
value: tmpState,
builder: (context, _) => _buildEditDialogWidgets(context)),
);
// update original state (no discard option to keep it simple)
orgState.update(tmpState);
}
但这也存在一些问题,例如:
- 我应该在哪里处理 tmpState?
- ProxyProvider 没有 .value 构造函数。
- 如果在 Provider 中创建了
create:
临时状态,当模式关闭时如何安全地访问该临时状态?
更新:在我当前的应用程序中,我在小部件树的顶部有一个 MultiProvider 小部件,它创建并提供多个过滤器状态对象。例如。FooFiltersState、BarFiltersState 和 BazFiltersState。它们是单独的类,因为这三个都扩展了一个ToggleableCollection<T> extends ChangeNotifier
或ToggleableCollectionPickerState<T> extends ToggleableCollection<T>
类。具有通用属性和功能(如 等)的抽象基bool areAllSelected()
类toggleAllSelection()
。
还有一个FiltersState extends ChangeNotifier
类,其中包含activeFiltersCount
一个取决于 Foo、Bar 和 Baz 过滤器状态的值。这就是我使用的原因
ChangeNotifierProxyProvider3<
FooFiltersState,
BarFilterState,
BazFilterState,
FiltersState>
提供 FiltersState 实例。
用户可以通过打开模态底部工作表来编辑这些过滤器,但对过滤器的更改不得反映在应用程序中,直到通过在稀松布上用胶带关闭底部工作表。编辑时可以在底部工作表上看到更改。
Foo 过滤器在底部工作表上显示为筹码。Bar 和 baz 过滤器在嵌套对话框窗口(从底部打开)中进行编辑。在编辑 Bar 或 Baz 过滤器集合时,更改必须仅反映在嵌套对话窗口内。确认嵌套对话框后,更改现在会反映在底部工作表上。如果嵌套对话框被取消,更改不会转移到底部工作表。和以前一样,这些更改在底部工作表关闭之前在应用程序内不可见。
为了避免不必要的小部件重建,选择器小部件用于显示过滤器值。
通过与 Yellowgray 的讨论,我认为我应该将所有非依赖值移出代理提供者。因此,临时代理提供者可以创建完全独立于原始状态对象的新临时状态对象。而对于其他对象,临时状态是从原始状态构建的,并像上面的示例一样传递给值构造函数。