You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter问题:文本编辑控制器数据无法传递至自定义验证构建器

解决密码验证器无法获取控制器最新值的问题

我想把密码输入框控制器的字符串传递给自定义的Validation Builder验证器,但测试发现,文本编辑控制器里的字符串没法传到验证构建器里,不过通过按钮访问该控制器的数据是正常的。我用的是form_validator包。

原代码片段

密码输入框部分:

child: TextFormField(
  controller: _repeatPassController,
  validator:
      ValidationBuilder(requiredMessage: "Bu alan gereklidir")
          .repeatPassword(passController.text)
          .build(),
  obscureText: true,
  decoration: InputDecoration(
      border: OutlineInputBorder(),
      labelText: 'Tekrar Şifre',
      hintText: 'Güvenli bir şifre giriniz'),
),

consts.dart中的验证器定义:

import 'package:form_validator/form_validator.dart';

class Consts {
  
  static final emailValidator = ValidationBuilder(
    requiredMessage: "Bu alan gereklidir",
  ).email("E-mail geçerli değil!").build();
  static final passValidator =
      ValidationBuilder(requiredMessage: "Bu alan gereklidir!")
          .password()
          .build();
}

extension CustomValidationBuilder on ValidationBuilder {
  password() => add((value) {
        if (value == null || value.isEmpty) {
          return "Şifre gereklidir";
        }

        if (value.length < 5) {
          return 'Şifreniz en az 5 karakter olmalıdır!';
        }
        return null;
      });
}

extension CustomValidationBuilderRepeatPassword on ValidationBuilder {
  ///检查重复密码是否匹配
  ///不匹配则返回错误信息
  repeatPassword(String password) => add((value) {
        if (value == null || value.isEmpty) {
          return "Bu alan gereklidir";
        }

        if (value != password) {
          print(value + " value"); ///输出:"myvalue value"
          print(password + " password"); ///输出:" password"(password为空)
          return 'Şifreler eşleşmiyor!';
        }
        return null;
      });
}

问题原因

核心问题是验证器初始化时就固定了密码值。Widget构建阶段,ValidationBuilder().repeatPassword(passController.text)会立即读取此时passController的text(初始为空),并把这个空值存在验证逻辑里。之后用户输入密码,控制器的text更新了,但验证器里保存的还是最初的空值,所以对比时永远不匹配,打印里password显示为空。而按钮点击是实时读取passController.text,所以能拿到最新值。

解决方案

修改自定义的repeatPassword扩展方法,让它接收TextEditingController而非String,这样在验证时可以实时获取控制器的最新text值。

1. 更新consts.dart中的验证器扩展

import 'package:form_validator/form_validator.dart';
import 'package:flutter/material.dart'; // 需导入以使用TextEditingController

class Consts {
  
  static final emailValidator = ValidationBuilder(
    requiredMessage: "Bu alan gereklidir",
  ).email("E-mail geçerli değil!").build();
  static final passValidator =
      ValidationBuilder(requiredMessage: "Bu alan gereklidir!")
          .password()
          .build();
}

extension CustomValidationBuilder on ValidationBuilder {
  password() => add((value) {
        if (value == null || value.isEmpty) {
          return "Şifre gereklidir";
        }

        if (value.length < 5) {
          return 'Şifreniz en az 5 karakter olmalıdır!';
        }
        return null;
      });
}

extension CustomValidationBuilderRepeatPassword on ValidationBuilder {
  /// 检查重复密码是否匹配,不匹配返回错误信息
  repeatPassword(TextEditingController passwordController) => add((value) {
        if (value == null || value.isEmpty) {
          return "Bu alan gereklidir";
        }
        
        final password = passwordController.text; // 实时读取最新密码
        if (value != password) {
          print("$value value");
          print("$password password");
          return 'Şifreler eşleşmiyor!';
        }
        return null;
      });
}

2. 修改TextFormField的validator参数

直接传递控制器实例,而不是它的text属性:

child: TextFormField(
  controller: _repeatPassController,
  validator: ValidationBuilder(requiredMessage: "Bu alan gereklidir")
      .repeatPassword(passController) // 传入控制器
      .build(),
  obscureText: true,
  decoration: InputDecoration(
      border: OutlineInputBorder(),
      labelText: 'Tekrar Şifre',
      hintText: 'Güvenli bir şifre giriniz'),
),

可选优化:实时触发验证

如果想让重复密码输入框在用户修改原密码时自动验证,可以给passController添加监听,在initState中加入:

@override
void initState() {
  super.initState();
  passController.addListener(() {
    // 假设你有表单的GlobalKey:_formKey
    if (_formKey.currentState != null) {
      _formKey.currentState!.validate();
    }
  });
}

@override
void dispose() {
  passController.dispose();
  _repeatPassController.dispose();
  super.dispose();
}

内容的提问来源于stack exchange,提问作者enes durmuş

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 02:54:25