#flutter #flutter-provider
Вопрос:
Я новичок в Flutter и в настоящее время работаю с поставщиками. Я извлекаю некоторый список статических массивов из api и сохраняю его поставщику. Я позволяю пользователю выбрать из этого списка и прикрепить к элементу, который он создает, используя форму.
Таким образом, каждый раз, когда пользователь пытается создать новый элемент, он/она должен видеть статический список с выбором, установленным в значение false.
Но переменная массива поставщика автоматически обновляется при вызове setState. Ниже приведена проблема, с которой я сталкиваюсь..
главная.дротик
MultiProvider(
providers: [
ChangeNotifierProvider<Info1Class>(
create: (ctx) => Info1Class(),
),
ChangeNotifierProvider<Info2Class>(
create: (ctx) => Info1Class(),
),
],
child: MaterialApp(
И в моем виджете с отслеживанием состояния в методе сборки. Я получаю информацию о поставщике таким образом.
screenArray.clear();
final t = Provider.of<Info1Class>(context, listen: false).dataArray;
screenArray.addAll(t);
Всякий раз, когда я вызываю setState для обновления элементов ScreenArray, данные поставщика также обновляются.
setState(() {screenArray[0].selected = true})
После setState(), если я напечатаю первый элемент массива данных поставщика, он будет отображаться как true.
print(Provider.of<Info1Class>(context, listen: false).dataArray[0].selected)
Мои Иждивенцы
provider: ^4.3.2 4
Есть ли способ избежать обновления данных поставщика и обновлять только переменную в моем виджете с отслеживанием состояния ?
Пожалуйста, дайте мне знать, если я что-то упускаю.. Спасибо за вашу помощь.
Комментарии:
1. Я получаю ту же ошибку только со списковыми типами данных, даже в provider и getx данные автоматически изменяются в setState
Ответ №1:
Я попробовал Getx и Провайдера как для этой проблемы, это проблема ссылки на объект, а не на Провайдера или getX, я справлялся со ссылкой на объекты, список или все данные. чтобы решить эту проблему, я создаю клон каждого объекта, а затем использую его.
// COMMON
String? uid;
String? username;
String? fullName;
String? email;
num? timestamp;
List<ProfilePhoto>? photos;
List<String>? skills;
Я добавляю один список объектов и другой список простых строк
Класс клонирования
MyUser.clone(MyUser? myUser) {
uid = myUser?.uid;
username = myUser?.username;
fullName = myUser?.fullName;
userType = myUser?.userType;
email = myUser?.email;
timestamp = myUser?.timestamp;
photos = ProfilePhoto.cloneList(myUser?.photos);
status = myUser?.status;
skills = [...(myUser?.skills ?? [])];
}
Конструктор
MyUser({
this.uid,
this.username,
this.fullName,
this.email,
this.timestamp,
this.photos,
this.skills,)};
Фотокласс
class ProfilePhoto {
String? id;
String? title;
String? url;
File? file;
bool? isDefau<
ProfilePhoto({
this.id,
this.title,
this.url,
this.file,
this.isDefault,
});
ProfilePhoto.clone(ProfilePhoto profilePhoto) {
id = profilePhoto.id;
title = profilePhoto.title;
url = profilePhoto.url;
file = profilePhoto.file;
isDefault = profilePhoto.isDefau<
}
static List<ProfilePhoto>? cloneList(List<ProfilePhoto>? items) {
if (items == null) return [];
List<ProfilePhoto>? newItems = [];
for (ProfilePhoto item in items) {
newItems.add(ProfilePhoto.clone(item));
}
return newItems;
}
}
Макет экрана
@override
void didChangeDependencies() {
super.didChangeDependencies();
final data = _userController.user;
MyUser? user = MyUser.clone(data);
}
void _onChangeDefault(int index) {
ProfilePhoto pp = _profilePhotos[index];
setState(() {
_profilePhotos.removeAt(index);
_profilePhotos.insert(0, pp);
});
}
это может быть не очень хорошим или оптимизированным решением, но это решает мою проблему автоматического обновления данных в диспетчере состояний