Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 使用小部件外部的GetX观察列表_Flutter_Dart_Getx - Fatal编程技术网

Flutter 使用小部件外部的GetX观察列表

Flutter 使用小部件外部的GetX观察列表,flutter,dart,getx,Flutter,Dart,Getx,我已经做了一些繁重的计算,然后在收到带有结果的列表时运行for循环,将它们添加到可观察列表中,其中items var items=[].obs 问题是,我正试图从splash控制器观察项目列表,一旦该列表[]我将导航到另一个屏幕,因此在onInit()中我有以下代码: class SplashController extends GetxController { @override void onInit() { final ItemsController _itemsContr

我已经做了一些繁重的计算,然后在收到带有结果的列表时运行for循环,将它们添加到可观察列表中,其中items var items=[].obs

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

class SplashController extends GetxController {
  @override
  void onInit() {
    final ItemsController _itemsController = Get.put(ItemsController());

    // TODO: implement onInit
    super.onInit();
    ever(_itemsController.items, (newItems) {
      print('new items here $newItems');
    });
  }
}
尽管填充了itemsController.items(在for循环之后,我打印了itemsController.items,并且它不是空的),但是添加项目时,splash控制器上的工作进程不会触发

我做错了什么?这是使用Getx观察小部件外部变量的正确方法吗? 有人能帮我吗

编辑:在项目控制器中,我以这种方式添加项目

add(item) => items.add(item)

这里有两个控制器,其中一个
ever
工作者监听另一个控制器的事件,其中该控制器的事件来自于在隔离中生成的数据

与任何其他异步数据源相比,我不知道在隔离中生成数据有什么特别之处,但我对隔离并不太熟悉

控制器 最后,调试输出结果显示处理可观察事件的工作人员(
接收到的项目…
):

非隔离页中的控制器 使用上述相同控制器的示例,没有有状态小部件页面和所有隔离内容的干扰

class SplashX extends GetxController {
  ItemsX itemsX;

  SplashX({this.itemsX});

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

    ever(itemsX.items, (items) => print('Received items: $items'));
  }
}

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

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

  /// Only relevant for SimplePage
  List<Widget> get texts => items.map((item) => Text('$item')).toList();
}

class SimplePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ItemsX ix = Get.put(ItemsX());
    SplashX sx = Get.put(SplashX(itemsX: ix));

    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            Expanded(
              flex: 10,
              child: Obx(
                    () => ListView(
                  children: ix.texts,
                ),
              ),
            ),
            Expanded(
              flex: 1,
              child: RaisedButton(
                child: Text('Add'),
                onPressed: () => ix.add('more...'),
              )
            )
          ],
        ),
      ),
    );
  }
}
class SplashX扩展了GetxController{
ItemsX ItemsX;
SplashX({this.itemsX});
@凌驾
void onInit(){
super.onInit();
曾经(itemsX.items,(items)=>print('receiveitems:$items');
}
}
类ItemsX扩展了GetxController{
RxList items=RxList();
无效添加(字符串项){
项目。添加(项目);
}
///仅与SimplePage相关
List get Text=>items.map((item)=>Text('$item')).toList();
}
类SimplePage扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
ItemsX ix=Get.put(ItemsX());
SplashX-sx=Get.put(SplashX(itemsX:ix));
返回脚手架(
正文:安全区(
子:列(
儿童:[
扩大(
弹性:10,
儿童:Obx(
()=>列表视图(
儿童:九、文本,
),
),
),
扩大(
弹性:1,
孩子:升起按钮(
子项:文本('Add'),
onPressed:()=>ix.add('more…'),
)
)
],
),
),
);
}
}

这里有两个控制器,其中一个
工作人员监听另一个控制器的事件,其中该控制器的事件来自于在隔离中生成的数据

与任何其他异步数据源相比,我不知道在隔离中生成数据有什么特别之处,但我对隔离并不太熟悉

控制器 最后,调试输出结果显示处理可观察事件的工作人员(
接收到的项目…
):

非隔离页中的控制器 使用上述相同控制器的示例,没有有状态小部件页面和所有隔离内容的干扰

class SplashX extends GetxController {
  ItemsX itemsX;

  SplashX({this.itemsX});

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

    ever(itemsX.items, (items) => print('Received items: $items'));
  }
}

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

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

  /// Only relevant for SimplePage
  List<Widget> get texts => items.map((item) => Text('$item')).toList();
}

class SimplePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ItemsX ix = Get.put(ItemsX());
    SplashX sx = Get.put(SplashX(itemsX: ix));

    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            Expanded(
              flex: 10,
              child: Obx(
                    () => ListView(
                  children: ix.texts,
                ),
              ),
            ),
            Expanded(
              flex: 1,
              child: RaisedButton(
                child: Text('Add'),
                onPressed: () => ix.add('more...'),
              )
            )
          ],
        ),
      ),
    );
  }
}
class SplashX扩展了GetxController{
ItemsX ItemsX;
SplashX({this.itemsX});
@凌驾
void onInit(){
super.onInit();
曾经(itemsX.items,(items)=>print('receiveitems:$items');
}
}
类ItemsX扩展了GetxController{
RxList items=RxList();
无效添加(字符串项){
项目。添加(项目);
}
///仅与SimplePage相关
List get Text=>items.map((item)=>Text('$item')).toList();
}
类SimplePage扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
ItemsX ix=Get.put(ItemsX());
SplashX-sx=Get.put(SplashX(itemsX:ix));
返回脚手架(
正文:安全区(
子:列(
儿童:[
扩大(
弹性:10,
儿童:Obx(
()=>列表视图(
儿童:九、文本,
),
),
),
扩大(
弹性:1,
孩子:升起按钮(
子项:文本('Add'),
onPressed:()=>ix.add('more…'),
)
)
],
),
),
);
}
}
继续,但不使用StatefulWidget,即无设置状态用法

SplashX中的
ever
工作人员将接收从隔离生成的项目。无状态小部件页面将显示从隔离发出的最新项

Splash控制器+
曾经
工人 项目控制员 无状态页面
类MyHomePageStateless扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
ItemsX ix=Get.put(ItemsX());//实例化ItemsController
IsolateX isox=Get.put(IsolateX(itemsX:ix));
SplashX-sx=Get.put(SplashX(itemsX:ix));
返回脚手架(
appBar:appBar(
标题:文本(“隔离无状态”),
),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
GetX(
生成器:(ix)=>文本(ix.items.isNotEmpty?ix.items.last:“”),
),
],
),
),
浮动操作按钮:GetBuilder(
生成器:(_ix)=>浮动操作按钮(
按下按钮:_ix.运行?isox.停止:isox.启动,
工具提示:_ix.running?'Timer stop':'Timer start',
子项:_ix.running?图标(Icons.stop):图标(Icons.play_箭头),
),
),
);
}
}
继续,但不使用StatefulWidget,即无设置状态用法

SplashX中的
ever
工作人员将接收从隔离生成的项目。无状态小部件页面将显示从隔离发出的最新项

Splash控制器+
曾经
  void _handleMessage(dynamic data) {
    //print('RECEIVED: ' + data);

    ix.add(data); // update observable

    setState(() {
      notification = data;
    });
  }
[GETX] "ItemsX" has been initialized
[GETX] "SplashX" has been initialized
I/flutter (19012): SEND: notification 1
I/flutter (19012): Received items: [notification 1]
I/flutter (19012): SEND: notification 2
I/flutter (19012): Received items: [notification 1, notification 2]
I/flutter (19012): SEND: notification 3
I/flutter (19012): Received items: [notification 1, notification 2, notification 3]
I/flutter (19012): done!
class SplashX extends GetxController {
  ItemsX itemsX;

  SplashX({this.itemsX});

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

    ever(itemsX.items, (items) => print('Received items: $items'));
  }
}

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

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

  /// Only relevant for SimplePage
  List<Widget> get texts => items.map((item) => Text('$item')).toList();
}

class SimplePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ItemsX ix = Get.put(ItemsX());
    SplashX sx = Get.put(SplashX(itemsX: ix));

    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            Expanded(
              flex: 10,
              child: Obx(
                    () => ListView(
                  children: ix.texts,
                ),
              ),
            ),
            Expanded(
              flex: 1,
              child: RaisedButton(
                child: Text('Add'),
                onPressed: () => ix.add('more...'),
              )
            )
          ],
        ),
      ),
    );
  }
}
class SplashX extends GetxController {
  ItemsX itemsX;

  SplashX({this.itemsX});

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

    ever(itemsX.items, (items) => print('Ever items: $items'));
  }
}
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();
}
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;
    }
  }
}
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),
        ),
      ),
    );
  }
}