Я пытаюсь получить данные из List внутри GetxController, но он продолжает возвращать null/Empty всякий раз, когда я пытаюсь получить к нему доступ внутри GetBuilder, даже если я уже присвоил ему значение. Внутри GetxController я могу распечатать значение, но когда я хочу его использовать, оно возвращает null/Empty
class BankController extends GetxController implements GetxService {
BankRepo bankRepo = BankRepo();
List<Bank> banks = [];
Future<void> getBanks() async {
ResponseModel response = await bankRepo.banks();
if (response.statusCode == 200) {
print(banks); // => []
banks = (response.data as List).map((e) => Bank.fromJson(e)).toList();
print(banks); // => [Instance of 'Bank', Instance of 'Bank', Instance of 'Bank', Instance of 'Bank', Instance of 'Bank', .....
update();
}
}
}
Воспроизвести:
Шаги для воспроизведения поведения:
Вызов функции getBanks из BankController
Получить банки из BankController в add_bank.dart, например БанкКонтроллер().банки
Распечатайте его на терминал, он возвращает пустой список
Ожидаемое поведение:
После вызова функции getBanks из BankController данные назначаются List<Bank> banks = [];, затем я создаю GetBuilder внутри add_bank.dart, чтобы получить данные внутри List<Bank> banks = []; и добавить их в раскрывающийся список. В раскрывающемся списке отобразится список всех банков.
Флаттер версия:
Flutter Channel stable, v2.10.3
Getx-версия:
get: ^4.6.5
Минимальный код воспроизведения:
add_bank.dart:
class AddBankView extends StatefulWidget {
const AddBankView({Key? key}) : super(key: key);
@override
State<AddBankView> createState() => _AddBankViewState();
}
class _AddBankViewState extends State<AddBankView> {
Bank selectedBank = Bank(name: "Select Bank", code: "");
@override
void initState() {
getBanks();
super.initState();
}
getBanks() async {
await BankController().getBanks();
BankController ctn = Get.find<BankController>();
print(ctn.banks); // => []
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: customAppbar("New Bank"),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: GetBuilder<BankController>(
init: BankController(),
builder: (bankController) {
print(bankController.banks); // => []
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 50,
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.symmetric(vertical: 20),
child: DropdownButtonHideUnderline(
child: GFDropdown(
padding: const EdgeInsets.symmetric(vertical: 15),
borderRadius: BorderRadius.circular(5),
border: const BorderSide(
color: Colors.transparent,
width: 0,
style: BorderStyle.none),
dropdownButtonColor: Colors.transparent,
dropdownColor:
Theme.of(context).colorScheme.surface,
value: selectedBank,
icon: Icon(
IconlyBold.arrowDownCircle,
color: Theme.of(context).colorScheme.onSurface,
size: 22,
),
onChanged: (value) {
setState(() {
selectedBank = value as Bank;
});
},
items: bankController.banks
.map((Bank value) => DropdownMenuItem<Bank>(
value: value,
child: CustomText(value.name,
color: theme.secondary
.withOpacity(0.85)),
))
.toList(),
),
),
),
]);
}),
),
),
),
);
}
}
Привязать контроллеры в get_init.dart:
initControllers() {
//Repositories
Get.lazyPut(() => BankRepo());
//Controllers
Get.lazyPut(() => BankController());
}
main.dart:
void main() async {
initControllers();
runApp(const MyApp());
}
Я спрашиваю вас, ребята, как я могу это решить. Если у вас есть какие-либо вопросы, вы можете задать их мне.





Вы использовали BankController на любой другой странице?
Если нет, используйте Get.put вместо Get.find: -
final BankController bankControl = Get.put(BankController());
Это немного сложно при использовании Get.lazyPut или Get.put или вместо Get.create и в зависимости от случая, в котором вы хотите, чтобы он действовал. Like Get.lazyPut не будет создавать экземпляр во время, а создаст его, когда вы вызовете Get.find.
И в вашем случае это код из вашего вопроса.
getBanks() async {
await BankController().getBanks();
BankController ctn = Get.find<BankController>();
print(ctn.banks); // => []
}
когда вы вызываете await BankController().getBanks();, вы буквально создаете новый экземпляр BankController, используя его конструктор. а затем в строке ниже вы создаете еще один экземпляр BankController, но с использованием инжектора зависимостей GetX (фабрика lazyPut). Таким образом, экземпляр ctn и экземпляр, созданный в этом BankController().getBanks(), — это совершенно разные экземпляры. и, очевидно, будет производить пустые банки.
Get.lazyPut или Get.put не просто сделали весь класс одноэлементным, вам нужно вызвать Get.find и использовать экземпляр из него, чтобы он действовал как один экземпляр.
Итак, в заключение ваш код должен быть таким:
BankController ctn = Get.find<BankController>();
await ctn.getBanks();
print(ctn.banks);
Более подробную информацию о разнице между put, lazyPut и create можно найти здесь:
Есть два способа сделать это: сделать это службой или контроллером.
Сервисный подход:
class BankService extends GetxService {}
файл main.dart
await Get.putAsync<BankService>(() async => BankService());
файл add_bank_view.dart
getBanks() async {
final ctn = Get.find<BankService>();
await ctn.getBanks();
print(ctn.banks); // => []
}
Подход контроллера:
class BankController extends GetxController {}
файл add_bank_view.dart
final controller = Get.put(BankController());
getBanks() async {
await controller.getBanks();
print(controller.banks); // => []
}
Пожалуйста, всегда включайте ваш импорт, чтобы мы точно знали, какие пакеты вы использовали! (Иногда я предполагал другой пакет, в котором использовался класс с тем же именем, и это делало мой ответ бесполезным... 😏)