Flutter 更改alertdialog中复选框的状态将更新提供程序数据

Flutter 更改alertdialog中复选框的状态将更新提供程序数据,flutter,dart,provider,Flutter,Dart,Provider,当我在Flatter应用程序中设计一个简单的屏幕时,我偶然看到了提供商软件包的一些奇怪行为(或者可能是一个Flatter,我不确定),经过几次尝试后,我都搞不清楚。屏幕仅包含一个选择用户的按钮,当点击该按钮选择用户时,将弹出一个警报对话框屏幕。“警报”对话框将显示所有用户的列表,旁边有一个复选框,如果先前选择了该用户,将选中该复选框。现在,您可以取消选中以前选中的用户或其他方式。最后,当点击“添加”按钮时,最终选中的用户将传递给提供者服务。更改复选框的状态不应将数据传递给提供者,而应在本地管理该

当我在Flatter应用程序中设计一个简单的屏幕时,我偶然看到了提供商软件包的一些奇怪行为(或者可能是一个Flatter,我不确定),经过几次尝试后,我都搞不清楚。屏幕仅包含一个选择用户的按钮,当点击该按钮选择用户时,将弹出一个警报对话框屏幕。“警报”对话框将显示所有用户的列表,旁边有一个复选框,如果先前选择了该用户,将选中该复选框。现在,您可以取消选中以前选中的用户或其他方式。最后,当点击“添加”按钮时,最终选中的用户将传递给提供者服务。更改复选框的状态不应将数据传递给提供者,而应在本地管理该状态。但是,我面临的问题是,通过更改复选框的状态,提供者服务中的
\u selectedUsers
属性得到了更新。这不是期望的行为,因为我甚至没有在代码中的任何地方调用
updateSelectedUsers
方法

  • 提供商服务
class MyService扩展了ChangeNotifier{
列表_selectedUsers=[];
列出get selectedUsers=>\u selectedUsers;
无效更新选定用户(列表用户){
_selectedUsers=用户;
notifyListeners();
}
未来的getAllUsers()异步{
///正在从服务器获取数据并返回所有用户。。。
返回fetchedAllUsers;
}
}
  • 警报屏幕
class\u MyDialog扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
MyService service=Provider.of(上下文,侦听:false);
列表_all=[];
列表_selected=service.selectedUsers;
返回警报对话框(
内容:FutureBuilder(
future:service.getAllUsers(),
生成器:(上下文,快照){
///…加载和错误处理代码位于此处。。。
_全部=快照数据;
返回StatefulBuilder(生成器:(上下文,设置状态){
返回SingleChildScrollView(
子:列(
子项:_all.map((e){
bool checked=false;
用于(用户u在_选中){
如果(u.id==e.id){checked=true;break;}
}
返回CheckboxListTile(
一旦更改:(val)=>setState(){
val?_selected.add(e):_selected.removehere((s)=>s.id==e.id));
},
值:选中,
标题:文本(如名称),
);
}).toList(),
),
);
});
},
),
行动:[
扁平按钮(
onPressed:()=>打印('尚未完成的事情'),
子项:文本('Add'),
),
],
);
}
}
    class MyService extends ChangeNotifier {
      
      List<User> _selectedUsers = [];

      List<User> get selectedUsers => _selectedUsers;

      void updateSelectedUsers(List<User> user) {
        _selectedUsers = user;
        notifyListeners();
      }
    
      Future<List<User>> getAllUsers() async {
        /// fetching data from server and return all users ...
        return fetchedAllUsers;
      }
    }
    class _MyDialog extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        MyService service = Provider.of<MyService>(context, listen: false);
        List<User> _all = [];
        List<User> _selected = service.selectedUsers;
    
        return AlertDialog(
          content: FutureBuilder<List<User>>(
            future: service.getAllUsers(),
            builder: (context, snapshot) {
    
              /// ... loading and error handling code goes here ...
    
              _all = snapshot.data;
              return StatefulBuilder(builder: (context, setState) {
                return SingleChildScrollView(
                  child: Column(
                    children: _all.map((e) {
                      bool checked = false;
                      for (User u in _selected) {
                        if (u.id == e.id) {checked = true; break;}
                      }
    
                      return CheckboxListTile(
                        onChanged: (val) => setState(() {
                          val ? _selected.add(e) : _selected.removeWhere((s) => s.id == e.id));
                        },
                        value: checked,
                        title: Text(e.name),
                      );
                    }).toList(),
                  ),
                );
              });
            },
          ),
          actions: [
            FlatButton(
              onPressed: () => print('something yet to be done'),
              child: Text('Add'),
            ),
          ],
        );
      }
    }