#flutter #dart #flutter-provider
#flutter #dart #поставщик flutter
Вопрос:
Я создаю простую CRUD-страницу в flutter. Прямо сейчас мой список загружается изначально, но когда я пытаюсь его обновить, он не создает виджет заново.
У меня есть класс, который отвечает за создание списка элементов, извлеченных из базы данных
class PlanList extends StatefulWidget {
PlanList({Key key}) : super(key: key);
@override
_PlanListState createState() => _PlanListState();
}
class _PlanListState extends State<PlanList> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
Provider.of<PlansProvider>(context, listen: true).loadPlans();
});
}
@override
Widget build(BuildContext context) {
return Consumer<PlansProvider>(
builder: (context, data, _) => ListView.builder(
itemCount: data.items.length,
itemBuilder: (BuildContext context, int index) {
return Text(data.items[index].type);
},
),
);
}
}
У меня также есть модель поставщика, которая отвечает за обновление списка.
class PlansProvider extends ChangeNotifier {
List<Payload> _plansList = [];
var _test = "test";
get test => _test;
UnmodifiableListView<Payload> get items => UnmodifiableListView(_plansList);
loadPlans() {
Plans _resu<
getPlans()
.then((value) => _result = value)
.then((value) => _plansList = _result.payload)
.whenComplete(() => notifyListeners());
}
}
Future<Plans> getPlans() async {
final response = await http.get('http://10.0.2.2:8080/plans');
if (response.statusCode == 200) {
return Plans.fromJson(json.decode(response.body));
} else {
throw Exception(response.statusCode);
}
}
и моя функция, которая вызывает функцию модели поставщика, когда я хочу перезагрузить элементы из базы данных
class CreatePlansPage extends StatefulWidget {
CreatePlansPage({Key key}) : super (key: key);
@override
_CreatePlansPageState createState() => _CreatePlansPageState();
}
class _CreatePlansPageState extends State<CreatePlansPage> {
var _name = '';
_handleTap(String string){
setState(() {
_name = string;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('$_name'),
),
body: ListView(
children: [
ListTile(
leading: Icon(Icons.add),
title: Text("Dinner"),
onTap: _handleTap('Dinner'),
),
ListTile(
leading: Icon(Icons.add),
title: Text("Dinner"),
onTap: _handleTap('Dinner'),
),
Center(
child: RaisedButton(
onPressed: (){
setState(() {
createPlans(_name);
Navigator.pop(context);
});
}
),
)
],
),
);
}
}
createPlans(String name) async {
final http.Response response = await http.post(
'http://10.0.2.2:8080/plans',
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'type': name,
}),
);
if (response.statusCode == 200) {
PlansProvider().loadPlans();
}
if (response.statusCode != 200) {
throw Exception('Failed!!!!');
}
}
Кто-нибудь знает, почему это не работает? Я что-то упустил?
Ответ №1:
в вашей createPlans
вызываемой вами функции PlansProvider().loadPlans();
, которая отличается от той, которая предоставляется при вызове Provider.of<PlansProvider>(context, listen: false).loadPlans();
RaisedButton(
onPressed: () async{
try{
final bool created = await createPlans(_name);
if(created) Provider.of<PlansProvider>(context, listen: false).loadPlans();
Navigator.pop(context);
} catch(e){
print('there was a en error'); //do somehting with the error
}
}
),
createPlans(String name) async {
final http.Response response = await http.post(
'http://10.0.2.2:8080/plans',
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'type': name,
}),
);
if (response.statusCode == 200) {
return true; //or just return, somehting to tell you it worked
}
if (response.statusCode != 200) {
throw Exception('Failed!!!!');
}
}
Также в вашем initState измените значение listen на false, чтобы избежать запуска кода более одного раза
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
Provider.of<PlansProvider>(context, listen: false).loadPlans();
// if you use true then everytime notifyListeners fires it will run this code, which is undesirable
});
Комментарии:
1. Это сработало. Спасибо, что нашли время ответить.