简体   繁体   English

无法使用无法直接访问 controller 的 Widget 使用 GetX

[英]Can't get GetX work with Widget that do not have direct access to controller

GetX works fine and update data if element have controller.如果元素有 controller,GetX 工作正常并更新数据。 But how to get it work if we have not direct to controller and widget done in way of changing date with onChange .但是,如果我们没有直接到 controller 和小部件以使用onChange更改日期的方式完成,如何让它工作。

I created small copy-paste example:我创建了小的复制粘贴示例:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:web_date_picker/web_date_picker.dart';

void main() {
  Get.put(SearchFormController());
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GetX Demo',
      home: MyHomePage(),
    );
  }
}

class SearchFormController extends GetxController {
  var endDate = Rxn<DateTime?>();

  setToNow() { // This function should set widget value
    endDate.value = DateTime.now();
    print('setToNow event: ${endDate.value}');
  }
}

class MyHomePage extends StatelessWidget {
  var ctrl = Get.find<SearchFormController>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Row(
        children: [
          Obx(() => SizedBox(
                width: 160,
                child: WebDatePicker(
                  initialDate: ctrl.endDate.value,
                  onChange: (value) {
                    if (value != null) {
                      ctrl.endDate.value = value;
                      print('onChange event: ${ctrl.endDate.value}');
                    }
                  },
                ),
              )),
          ElevatedButton(
            onPressed: () {
              ctrl.setToNow();
            },
            child: Text("Set Date"),
          ),
        ],
      ),

    );
  }
}

pubspec.yaml: pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  web_date_picker: ^1.0.0+3
  get: ^4.6.5  

In this code I can't set date by clicking on Set Date button.在此代码中,我无法通过单击Set Date按钮来设置日期。

I looked at widget code and it's controller is hidden with follow realization:我查看了小部件代码,它的 controller 被隐藏,实现如下:

class _WebDatePickerState extends State<WebDatePicker> {
  final FocusNode _focusNode = FocusNode();

  late OverlayEntry _overlayEntry;

  final LayerLink _layerLink = LayerLink();

  final _controller = TextEditingController();

  late DateTime? _selectedDate;
  late DateTime _firstDate;
  late DateTime _lastDate;

  bool _isEnterDateField = false;

  @override
  void initState() {
    super.initState();

    _selectedDate = widget.initialDate;
    _firstDate = widget.firstDate ?? DateTime(2000);
    _lastDate = widget.lastDate ?? DateTime(2100);

    if (_selectedDate != null) {
      _controller.text = _selectedDate?.parseToString(widget.dateformat) ?? '';
    }

    _focusNode.addListener(() {
      if (_focusNode.hasFocus) {
        _overlayEntry = _createOverlayEntry();
        Overlay.of(context)?.insert(_overlayEntry);
      } else {
        _controller.text = _selectedDate.parseToString(widget.dateformat);
        widget.onChange.call(_selectedDate);
        _overlayEntry.remove();
      }
    });
  }

  void onChange(DateTime? selectedDate) {
    _selectedDate = selectedDate;
    _controller.text = _selectedDate.parseToString(widget.dateformat);

    _focusNode.unfocus();
  }
...

Widget code https://github.com/duchdtran/web_date_picker/blob/master/lib/src/web_date_picker.dart#L98小部件代码https://github.com/duchdtran/web_date_picker/blob/master/lib/src/web_date_picker.dart#L98

Could anybody provide example how to get button work to set widget value?谁能提供示例如何让按钮工作以设置小部件值?

I experienced similar problems and solved them desribed as below.我遇到了类似的问题并解决了如下描述的问题。

It seems WebDatePicker does not process the value change.似乎 WebDatePicker 不处理值更改。 Try putting it in its own StatelessWidget :尝试将其放入自己的StatelessWidget

class MyWebDatePicker extends StatelessClass {
  final DateTime dt;
  var ctrl = Get.find<SearchFormController>();

  MyWebDatePicker(this.dt);

  Widget build(BuildContext context) {
    return WebDatePicker(
                  initialDate: dt,
                  onChange: (value) {
                    if (value != null) {
                      ctrl.endDate.value = value;
                      print('onChange event: ${value}');
                    }
                  },
                );
  }
}

Then, call it like given below.然后,像下面给出的那样调用它。 This code looks unusual, but it forces Obx to call MyWebDatePicker with the current DateTime value:此代码看起来不寻常,但它强制Obx使用当前DateTime值调用MyWebDatePicker

Obx(() => SizedBox(
  width: 160,
  child: MyWebDatePicker(ctrl.endDate.value)
  )
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM