如何监听 TextController 内部的变化?

How to listen changes inside TextController?

我正在使用 GetX。我需要监听 TextController 中的变化。以下代码不起作用:

class Controller extends GetxController{

  final txtList = TextEditingController().obs;

  @override
  void onInit() {
    debounce(txtList, (_) { 
      print("debouce$_");
      }, time: Duration(seconds: 1));
    super.onInit();
  }

}

当我从 UI 更改 txtList 值时,它不打印任何内容。我想这是因为它没有检查 txtList.

中的文本字段

如何让它发挥作用?

检查此代码段以收听 TextEditingController 文本更改侦听器

    import 'package:flutter/material.dart';

    void main() async {
      runApp(MyApp());
    }

    class MyApp extends StatefulWidget {
      const MyApp({Key? key}) : super(key: key);

      @override
      _MyAppState createState() => _MyAppState();
    }

    class _MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData(),
          darkTheme: ThemeData.dark(),
          home: const HomePage(),
        );
      }
    }

    class HomePage extends StatefulWidget {
      const HomePage({Key? key}) : super(key: key);

      @override
      State<HomePage> createState() => _HomePageState();
    }

    class _HomePageState extends State<HomePage> {
      final TextEditingController controller = TextEditingController();
      @override
      void initState() {
        super.initState();
        controller.addListener(_printLatestValue);
      }

      void _printLatestValue() {
        print('Second text field: ${controller.text}');
      }

      @override
      void dispose() {
        controller.dispose();
        super.dispose();
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: TextField(
            controller: controller,
          ),
        );
      }
    }
  1. 通过TextEditingController.text,我们已经可以得到变化的文本输入值,所以它不需要.obs
  2. 要为 debounce 传递参数,我们应该传递值本身:txtList.text。 (参见此处:https://github.com/jonataslaw/getx/blob/master/documentation/en_US/state_management.md
final txtList = TextEditingController(); // 1. here

  @override
  void onInit() {
    debounce(txtList.text, (_) {  // 2. here
      print("debouce$_");
     }, time: Duration(seconds: 1));
    super.onInit();
  }

这可能有效。

=================== 已添加 11/21 ==================

举个例子。我知道 RxString 变量似乎是 TextEditingController.text 的重复项,但 GetX 的 debounce 函数需要 RxString 类型变量作为参数。我试图找到更优雅的方法来做到这一点,但我找不到任何东西。如果有人知道更好的方法,请告诉我。

// in controller

  late final TextEditingController textController;
  final RxString userInput = "".obs;

  @override
  void onInit() {
    super.onInit();
    textController = TextEditingController();
    userInput.value = textController.text;

    textController.addListener(() {
            userInput.value = textController.text;
        }
    );

    
    debounce(userInput, (_) {
      print("debouce$_");
     }, time: Duration(seconds: 1));
  }


您需要将 RxInterface 传递给 debounce 才能通过 GetX 执行此操作。只需创建一个 RxString 并向控制器添加一个侦听器,然后将 RxString 传递给 debounce.

class Controller extends GetxController {
  final txtList = TextEditingController();

  RxString controllerText = ''.obs;

  @override
  void onInit() {
    txtList.addListener(() {
      controllerText.value = txtList.text;
    });
    
    debounce(controllerText, (_) {
      print("debouce$_");
    }, time: Duration(seconds: 1));
    super.onInit();
  }
}

然后在应用程序的任何页面上,您都可以将该控制器传入文本字段,它会在用户停止输入 1 秒后打印该值。

class Home extends StatelessWidget {
 final controller = Get.put(Controller());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextField(controller: controller.txtList), // this will print
      ),
    );
  }
}

如果您需要该值用于任何其他用途,也可以随时通过 controller.controllerText.value.

访问它