Flutter Getx-"Xxx"未找到.您需要调用"Get.put(Xxx())"-但我打电话给Get.put(Xxx()) [英] Flutter Getx - "Xxx" not found. You need to call "Get.put(Xxx())" - But i have called Get.put(Xxx())

查看:233
本文介绍了Flutter Getx-"Xxx"未找到.您需要调用"Get.put(Xxx())"-但我打电话给Get.put(Xxx())的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个全局绑定类来初始化一些服务,我需要立即对其进行初始化:

I have this global bindings class to initialise some services and I need it to be initialised straight away:

import 'package:get/get.dart';
import 'package:vepo/data/data_provider/local_data_provider.dart';
import 'package:vepo/data/data_source/local_data_source.dart';

import 'services/authentication_service.dart';

class GlobalBindings extends Bindings {
  final LocalDataProvider _localDataProvider = LocalDataProvider();
  @override
  void dependencies() {
    Get.put<AuthenticationService>(AuthenticationService(), permanent: true);
    Get.put<LocalDataProvider>(_localDataProvider, permanent: true);
    Get.put<LocalDataSource>(LocalDataSource(_localDataProvider),
        permanent: true);
  }
}

哪个在我的initialBindings中?

Which is in my initialBindings:

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Vepo',
      initialRoute: AppPages.INITIAL,
      initialBinding: GlobalBindings(),
      transitionDuration: const Duration(milliseconds: 500),
      defaultTransition: Transition.rightToLeft,
      getPages: AppPages.routes,
      home: Root(),
      theme: homeTheme,
    );
  }
}

然后在类构造函数中尝试查找"它:

Then in a class constructor I try to "find" it:

class UserLocalRepository extends VpService implements IUserLocalRepository {
  UserLocalRepository() {
    localDataSource = Get.find<LocalDataSource>();
  }

  LocalDataSource localDataSource;

并得到此错误:

══════ Exception caught by widgets library ═══════════════════════════════════
The following message was thrown building App(dirty):
"LocalDataSource" not found. You need to call "Get.put(LocalDataSource())" or "Get.lazyPut(()=>LocalDataSource())"

The relevant error-causing widget was
App
lib/main.dart:17
When the exception was thrown, this was the stack
#0      GetInstance.find
package:get/…/src/get_instance.dart:272
#1      Inst.find
package:get/…/src/extension_instance.dart:66
#2      new UserLocalRepository
package:vepo/…/user/user_local_repository.dart:10
#3      new LoggedOutNickNameBinding
package:vepo/…/logged_out_nickname/logged_out_nick_name_binding.dart:11
#4      AppPages.routes
package:vepo/…/routes/app_pages.dart:29
...
════════════════════════════════════════════════════════════════════════════════

这是错误消息中提到的绑定:

This is the binding mentioned in the error message:

class LoggedOutNickNameBinding extends Bindings {
  LoggedOutNickNameBinding() {
    _repository = Get.put(UserLocalRepository());
  }

  IUserLocalRepository _repository;

  @override
  void dependencies() {
    Get.lazyPut<LoggedOutNickNameController>(
      () => LoggedOutNickNameController(_repository),
    );
  }
}

为什么"initialBindings"不正确?未初始化,以便我的应用可以找到"他们在应用启动时?

Why are the "initialBindings" not initialised so that my app can "find" them when the app starts up?

推荐答案

我猜想是在调用GlobalBindings.dependencies()方法以及何时需要这些资源时,时序/顺序不匹配.

I'm guessing that there's a timing / ordering mismatch with when your GlobalBindings.dependencies() method gets called and when you need those resources.

您可以尝试将Bindings类 prior 初始化为GetMaterialApp,而不是将Bindings类传递给 GetMaterialApp.

You could try initializing your Bindings class prior to GetMaterialApp instead of passing your Bindings class to GetMaterialApp.

void main() async {
  //WidgetsFlutterBinding.ensureInitialized(); // uncomment if needed for resource initialization
  GlobalBindings().dependencies();
  runApp(MyApp());
}

切线

在这里只是猜测,但是您准备通过Get.put初始化的某些类在准备使用之前是缓慢启动(即异步)的吗?

Tangent

Just guessing here, but are some of the classes you're initializing via Get.put are slow-startup (i.e. async) before they are ready to use?

如果可以的话,可以使用

If so you could use

Get.putAsync<YourClass>(() async {
 // init YourClass here
 return await YourClass.slowInit();

}

示例

我最近进行了一个练习,即在加载应用进行用户交互之前执行异步绑定初始化.这是代码:

Example

I recently ran an exercise of performing async Bindings initialization prior to app being loaded for user interaction. Here's the code:

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

enum Version {
  lazy,
  wait
}
// Cmd-line args/Env vars: https://stackoverflow.com/a/64686348/2301224
const String version = String.fromEnvironment('VERSION');
const Version running = version == "lazy" ? Version.lazy : Version.wait;

void main() async {
  //WidgetsFlutterBinding.ensureInitialized(); // if needed for resources
  if (running == Version.lazy) {
    print('running LAZY version');
    LazyBindings().dependencies();
  }

  if (running == Version.wait) {
    print('running AWAIT version');
    await AwaitBindings().dependencies(); // await is key here
  }

  runApp(MyApp());
}

class LazyBindings extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut<MyDbController>(() => MyDbController());
  }
}

/// Simulates a slow (2 sec.) init of a data access object.
/// Calling [await] dependencies(), your app will wait until dependencies are loaded.
class AwaitBindings extends Bindings {
  @override
  Future<void> dependencies() async {
    await Get.putAsync<MyDbController>(() async {
      Dao _dao = await Dao.createAsync();
      return MyDbController(myDao: _dao);
    });
  }
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final MyDbController dbc = Get.find();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('GetX Bindings'),
      ),
      body: Center(
        child: Obx(() => Text(dbc.dbItem.value)),
      ),
    );
  }
}

class MyDbController extends GetxController {
  Dao myDao;

  MyDbController({this.myDao});

  RxString dbItem = 'Awaiting data'.obs;

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

  Future<void> initDao() async {
    // instantiate Dao only if null (i.e. not supplied in constructor)
    myDao ??= await Dao.createAsync();
    dbItem.value = myDao.dbValue;
  }
}

class Dao {
  String dbValue;

  Dao._privateConstructor();

  static Future<Dao> createAsync() async {
    var dao = Dao._privateConstructor();
    print('Dao.createAsync() called');
    return dao._initAsync();
  }

  /// Simulates a long-loading process such as remote DB connection or device
  /// file storage access.
  Future<Dao> _initAsync() async {
    await Future.delayed(Duration(seconds: 2), () => dbValue = 'Some DB data');
    print('Dao._initAsync done');
    return this;
  }
}

这篇关于Flutter Getx-"Xxx"未找到.您需要调用"Get.put(Xxx())"-但我打电话给Get.put(Xxx())的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆