我试图在无状态小部件中使用TextFormField以及ScopedModel来处理其中的文本并面临如下的各种问题。
对此有何解决方案?
附加问题的示例代码。
class LoginPageStateless extends StatelessWidget {
final loginUsernameController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: true,
body: ScopedModelDescendant<AccountModel>(
builder: (context, child, model) {
return Form(
//key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
style: TextStyle(fontSize: 15.0),
decoration: InputDecoration(
labelText: 'Email id',
hintText: '[email protected]',
),
controller: loginUsernameController,
onFieldSubmitted: model.updateLoginUsernameText,
),
TextFormField(
style: TextStyle(fontSize: 15.0),
decoration: InputDecoration(
labelText: 'Password',
),
controller: loginUsernameController,
onFieldSubmitted: model.updateLoginUsernameText,
obscureText: true,
),
],
),
);
},
),
);
}
}
您不能也不应该使用Stateless
小部件来存储长期变量。
问题是,这正是你想要的。 TextEditingController
是一个应该在渲染之间保持的类实例。但是通过将其存储到StatelessWidget
中,您基本上可以在每次更新后重新创建它。
您应该将您的小部件转换为Stateful
。并将该控制器移动到State
部分
到目前为止我还没有使用TextFormField,我总是使用TextField()来实现它的简单性和灵活性。我在使用Redux和无状态小部件时遇到了类似的问题,因为我在顶级商店中只有一个事实来源。所以,我必须在ViewModel中创建一些回调,然后将该回调分配给文本字段回调'onChanged',它接受一个字符串参数。
CustomTextWidgetWrapper(
onChangedCallback: viewModel.onChanged
),
在我做的小部件包含的TextField中(没有提供更多细节)
new TextField(
controller: myController, // no use practically now
onChanged: onChangedCallback,
在视图模型中,我将字符串和调度发送到中央存储,以便在其他小部件中重用,例如一个获取数据并发送到服务器的按钮
static ViewModel fromStore(Store<AppState> store) {
return new ViewModel(
onChanged: (String textFieldText) {
// I call dispatch or an API here if I want
store.dispatch(new CallAPI(params: textFieldText);