【问题标题】:How to listen changes inside TextController?如何监听 TextController 内部的变化?
【发布时间】:2021-12-12 21:27:21
【问题描述】:

我正在使用 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().obs 不起作用!要么使用文本字段的 onchange 属性,要么在 Init 上向控制器添加侦听器并尝试打印。
  • @KrishBhanushali,你能举个例子吗?

标签: flutter flutter-getx


【解决方案1】:

例如检查这个 sn-p 以收听 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,
          ),
        );
      }
    }

【讨论】:

  • 但是如何找到工作debounce
  • 如果你想去抖动,我们有你必须使用rxdart
  • 但是否有可能让它只与 GetX 一起工作?
  • @HemanhS GetX 实际上有一个debounce 方法,没有必要直接使用RxDart
【解决方案2】:
  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));
  }


【讨论】:

  • 我收到错误:The argument type 'String' can't be assigned to the parameter type 'RxInterface&lt;Object?&gt;'
  • 对不起。您可能需要定义RxString 类型变量并使用它来代替txtList.text
  • 但我的类型是TextEditingController,而不是RxString。 surch 类型的控制器需要TextEditingController。你能给我看完整的例子吗?
  • 抱歉回复晚了。我用示例编辑了我的答案。 @DmitryBubnenkov
【解决方案3】:

您需要将 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 访问它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2020-08-13
    • 2021-09-21
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    相关资源
    最近更新 更多