在小部件之外使用 GetX 观察列表

i6x*_*x86 3 dart flutter flutter-getx

我有一个isolate,它进行了一些繁重的计算,然后在接收结果列表时运行一个for循环,将它们添加到可观察列表中,其中包含items var items = [].obs;

\n

问题是我试图从启动控制器观察项目列表,一旦列表 != [] 我将导航到另一个屏幕,所以在 onInit() 中我有以下代码:

\n
class SplashController extends GetxController {\n  @override\n  void onInit() {\n    final ItemsController _itemsController = Get.put(ItemsController());\n\n    // TODO: implement onInit\n    super.onInit();\n    ever(_itemsController.items, (newItems) {\n      print('new items here $newItems');\n    });\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

尽管 itemsController.items 已填充(在 for 循环之后,我打印了 itemsController.items 并且它不是空的),但添加项目时,飞溅控制器上的工作程序不会触发。

\n

我在这里做错了什么?这是使用 Getx 观察小部件外部变量的正确方法吗?\n有人可以帮我解决这个问题吗?

\n

编辑:在项目控制器中 I\xe2\x80\x99m 以这种方式添加项目

\n
add(item) => items.add(item)\n
Run Code Online (Sandbox Code Playgroud)\n

Bak*_*ker 6

继续Isolate 示例,但不使用 StatefulWidget,即不使用 setState。

SplashX 中的工作人员ever将接收从 Isolate 生成的项目。Stateless Widget 页面将显示从 Isolate 发出的最新项目。

SplashController +ever工作人员

class SplashX extends GetxController {
  ItemsX itemsX;

  SplashX({this.itemsX});

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

    ever(itemsX.items, (items) => print('Ever items: $items'));
  }
}
Run Code Online (Sandbox Code Playgroud)

物品控制器

class ItemsX extends GetxController {
  RxList<String> items = RxList<String>();
  bool running = false;

  void add(String item) {
    items.add(item);
  }

  void updateStatus(bool isRunning) {
    running = isRunning;
    update();
  }

  void reset() {
    items.clear();
  }

  /// Only relevant for UnusedControllerPage
  List<Widget> get texts => items.map((item) => Text('$item')).toList();
}
Run Code Online (Sandbox Code Playgroud)

隔离控制器

class IsolateX extends GetxController {
  IsolateX({this.itemsX});

  ItemsX itemsX;
  Isolate _isolate;
  static int _counter = 0;
  ReceivePort _receivePort;
  bool running = false;

  static void _checkTimer(SendPort sendPort) async {
    Timer.periodic(Duration(seconds: 1), (Timer t) {
      _counter++;
      String msg = 'notification ' + _counter.toString();
      print('SEND: ' + msg);
      sendPort.send(msg);
    });
  }

  void _handleMessage(dynamic data) {
    itemsX.add(data); // update observable
  }

  void updateStatus(bool isRunning) {
    running = isRunning;
    update();
  }

  void start() async {
    itemsX.reset();
    updateStatus(true);
    _receivePort = ReceivePort();
    _isolate = await Isolate.spawn(_checkTimer, _receivePort.sendPort);
    _receivePort.listen(_handleMessage, onDone:() {
      print("done!");
    });
  }

  void stop() {
    if (_isolate != null) {
      updateStatus(false);
      _receivePort.close();
      _isolate.kill(priority: Isolate.immediate);
      _isolate = null;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

无状态页面

class MyHomePageStateless extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ItemsX ix = Get.put(ItemsX()); // Instantiate ItemsController
    IsolateX isox = Get.put(IsolateX(itemsX: ix));
    SplashX sx = Get.put(SplashX(itemsX: ix));

    return Scaffold(
      appBar: AppBar(
        title: Text('Isolate Stateless'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            GetX<ItemsX>(
              builder: (ix) => Text(ix.items.isNotEmpty ? ix.items.last : ''),
            ),
          ],
        ),
      ),
      floatingActionButton: GetBuilder<IsolateX>(
        builder: (_ix) => FloatingActionButton(
          onPressed: _ix.running ? isox.stop : isox.start,
          tooltip: _ix.running ? 'Timer stop' : 'Timer start',
          child: _ix.running ? Icon(Icons.stop) : Icon(Icons.play_arrow),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)