为啥 reactTextFields 在与 FormGroup 不同的类中不能正常工作?

Posted

技术标签:

【中文标题】为啥 reactTextFields 在与 FormGroup 不同的类中不能正常工作?【英文标题】:Why reactiveTextFields doesn't work well when in different class than FormGroup?为什么 reactTextFields 在与 FormGroup 不同的类中不能正常工作? 【发布时间】:2021-05-04 11:17:36 【问题描述】:

我有一个类,我初始化了FormGroup

final form = FormGroup(
    
      'oldPassword': FormControl<String>(
        value: null,
        validators: [
          Validators.required,
        ],
      ),
      'newPassword': FormControl<String>(
        value: null,
        touched: true,
        validators: [
          Validators.pattern(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]8,$',
              validationMessage:
                  'Required: \n * One uppercase and one downcase letter \n * Atleast one number \n * Atleast 8 characters')
        ],
      ),
      'repeatPassword': FormControl<String>(
        value: null,
        validators: [
          Validators.required,
        ],
      ),
    ,
    validators: [
      Validators.mustMatch(
        'newPassword',
        'repeatPassword',
      )
    ],
  );

我创建了一个 StatefullWidget 类ReactivePasswordField

import 'package:flutter/material.dart';
import 'package:reactive_forms/reactive_forms.dart';

class ReactivePasswordField extends StatefulWidget 
  final String controlName;
  final String hintText;
  final Function() onSubmitted;

  const ReactivePasswordField(
    required this.controlName,
    required this.hintText,
    required this.onSubmitted,
  );

  @override
  _ReactivePasswordFieldState createState() => _ReactivePasswordFieldState();


class _ReactivePasswordFieldState extends State<ReactivePasswordField> 
  bool isObscure = true;
  IconData icon = Icons.visibility_off;
  late String controlName;

  @override
  void initState() 
    controlName = widget.controlName;
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return ReactiveTextField(
      autofocus: true,
      obscureText: isObscure,
      formControlName: 'oldPassword',
      onSubmitted: () => widget.onSubmitted,
      validationMessages: (control) => 
        'required': 'Field cannot be empty.',
        'mustMatch': 'New password must match.'
      ,
      decoration: InputDecoration(
        filled: true,
        prefixIcon: Icon(
          Icons.lock,
          color: Color(0xffe96cbd),
        ),
        hintText: widget.hintText,
        suffixIcon: GestureDetector(
            onTap: () 
              if (isObscure) 
                setState(() 
                  icon = Icons.visibility_off;
                  isObscure = false;
                );
               else 
                setState(() 
                  icon = Icons.visibility;
                  isObscure = true;
                );
              
            ,
            child: Icon(
              icon,
              color: Color(0xff3A4A78),
            )),
        border: OutlineInputBorder(
          borderSide: BorderSide.none,
          borderRadius: BorderRadius.circular(20.0),
        ),
      ),
    );
  

我这样做了,因为我希望每个 ReactivePasswordField 都有自己的状态来管理显示和隐藏输入视图。 问题是当我输入ReactivePasswordField 之一时,其他人具有相同的输入。 我的验证器也不起作用。 我该如何解决?

我如何在初始化 FormGroup 的类中使用我的ReactivePasswordFields

SingleChildScrollView(
          child: ReactiveForm(
        formGroup: form,
        child: Column(
          children: [
            ReactivePasswordField(
                controlName: 'oldPassword',
                hintText: 'Current password',
                onSubmitted: () => form.focus('newPassword')),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 8.0),
              child: ReactivePasswordField(
                controlName: 'newPassword',
                hintText: 'New password',
                onSubmitted: () => form.focus('repeatPassword'),
              ),
            ),
            ReactivePasswordField(
              controlName: 'repeatPassword',
              hintText: 'Repeat password',
              onSubmitted: () => ,
            )
          ],
        ),
      )),

【问题讨论】:

【参考方案1】:

我刚刚在ReactivePasswordField 课堂上搞砸了。 有变化:

import 'package:flutter/material.dart';
import 'package:reactive_forms/reactive_forms.dart';

class ReactivePasswordField extends StatefulWidget 
  final String controlName;
  final String hintText;
  final Function() onSubmitted;

  const ReactivePasswordField(
    required this.controlName,
    required this.hintText,
    required this.onSubmitted,
  );

  @override
  _ReactivePasswordFieldState createState() => _ReactivePasswordFieldState();


class _ReactivePasswordFieldState extends State<ReactivePasswordField> 
  bool isObscure = true;
  IconData icon = Icons.visibility_off;


  @override
  Widget build(BuildContext context) 
    return ReactiveTextField(
      autofocus: true,
      obscureText: isObscure,

//-------------CHANGE--------------------------------------------------------
//Here i had static String instead of widget.controlName 
      formControlName: widget.controlName,
      onSubmitted: () => widget.onSubmitted,
      validationMessages: (control) => 
        'required': 'Field cannot be empty.',
        'mustMatch': 'New password must match.'
      ,
      decoration: InputDecoration(
        filled: true,
        prefixIcon: Icon(
          Icons.lock,
          color: Color(0xffe96cbd),
        ),
        hintText: widget.hintText,
        suffixIcon: GestureDetector(
            onTap: () 
              if (isObscure) 
                setState(() 
                  icon = Icons.visibility_off;
                  isObscure = false;
                );
               else 
                setState(() 
                  icon = Icons.visibility;
                  isObscure = true;
                );
              
            ,
            child: Icon(
              icon,
              color: Color(0xff3A4A78),
            )),
        border: OutlineInputBorder(
          borderSide: BorderSide.none,
          borderRadius: BorderRadius.circular(20.0),
        ),
      ),
    );
  

【讨论】:

以上是关于为啥 reactTextFields 在与 FormGroup 不同的类中不能正常工作?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 React-Native 无法在与 Expo 的 Android 连接上启动项目?

为啥我不能创建在与类定义相同的命名空间中定义的 C++ 类的实例?

为啥使用与父级一起声明的 std::function 在与子级一起使用时会显示错误?

为啥这个 PL-SQL 循环只有在与 DDL 语句分开执行时才起作用?

为啥 LLVM 的泄漏消毒剂在与其他启用的消毒剂一起使用时不起作用

为啥在与数组中的字段匹配时,mongoDB聚合中的查找中的管道不起作用?