gpt4 book ai didi

dart - 正在重新创建 Flutter BLoC

转载 作者:IT王子 更新时间:2023-10-29 06:38:11 25 4
gpt4 key购买 nike

我正在探索 Flutter 和 bloc 模式,并练习我正在制作一个关于比萨饼的应用。

我正在使用 BlocProvider 访问 block 。它来自 generic_bloc_provider包裹。它是使用 InheritedWidget 结合 StatelessWidget 的基本实现。

我有一个包含两个可编辑文本字段的页面,用于显示我要创建的比萨饼的名称和价格。它得到了一个 Bloc 的支持。

代码如下:

AddPizzaPage.dart :

class AddPizzaPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("Building AddPizzaPage");
return Scaffold(
appBar: AppBar(
title: Text("Adding Pizza"),
),
body: BlocProvider(
bloc: AddPizzaBloc(),
child: ModifyPizzaWidget(),
),
);
}
}

ListPage.dart:

class ModifyPizzaWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final addPizzaBloc = BlocProvider.of<AddPizzaBloc>(context);
return Container(
margin: EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: "Nom de la pizza"),
onChanged: (name) {
addPizzaBloc.pizzaNameSink.add(name);
},
),
TextField(
decoration: InputDecoration(hintText: "Prix de la pizza"),
keyboardType: TextInputType.number,
onChanged: (price) {
addPizzaBloc.pizzaPriceSink.add(price);
},
),
IconButton(
icon: Icon(Icons.check),
iconSize: 40,
onPressed: () {
addPizzaBloc.evenSink.add(AddPizzaEvent.VALIDATE);
Navigator.of(context).pop();
},
)
],
),
);
}
}

AddPizzaBloc.dart :

enum AddPizzaEvent {
VALIDATE
}

class AddPizzaBloc extends Bloc {
final _pizza = Pizza.empty();
final _pizzaSubject = BehaviorSubject<Pizza>();
final _repository = PizzaRepository();

Sink<String> get pizzaNameSink => _pizzaNameController.sink;
final _pizzaNameController = StreamController<String>();

Sink<String> get pizzaPriceSink => _pizzaPriceController.sink;
final _pizzaPriceController = StreamController<String>();

Sink<AddPizzaEvent> get evenSink => _eventSink.sink;
final _eventSink = StreamController<AddPizzaEvent>();

AddPizzaBloc() {
print("Created");
_pizzaNameController.stream.listen(_addPizzaName);
_pizzaPriceController.stream.listen(_addPizzaPrice);
_eventSink.stream.listen(_onEventReceived);
}

dispose() {
print("Disposed");
_pizzaSubject.close();
_pizzaNameController.close();
_pizzaPriceController.close();
_eventSink.close();
}

void _addPizzaName(String pizzaName) {
_pizza.name = pizzaName;
print(_pizza);
}

void _addPizzaPrice(String price) {
var pizzaPrice = double.tryParse(price) ?? 0.0;
_pizza.price = pizzaPrice;
print(_pizza);
}

void _onEventReceived(AddPizzaEvent event) {
print("Received $event");
if (event == AddPizzaEvent.VALIDATE) {
print(_pizza);
_repository.addPizza(_pizza);
}
}
}

我的问题是,我将正在构建的披萨存储在 block 内,但重建了小部件,因此重建了 block ,我失去了状态。

完整代码可在 gitlab 上获得

我不知道如何使用 bloc 为 addPizza 表单提供动力。

最佳答案

发生这种情况是因为您在构建方法中创建了 BLoC 的实例:

BlocProvider(
bloc: Bloc(),
child: ...
)

结果是任何重建都不会重用以前的实例(也有一些可怕的内存泄漏)。

解决方案是制作一个 StatefulWidget 并在 initState 中创建该 BLoC 实例,然后是一个 dispose 重写以清除内容。

但是因为你已经在使用一个包,你可以使用 provider反而。它是一种流行的替代方案,可以完成上面列出的所有事情。

因此,您的 BlocProvider 用法变为:

StatefulProvider(
valueBuilder: (_) => AddPizzaBloc(),
dispose: (_, bloc) => bloc.dispose(),
child: // ...
),

然后这样得到:

Provider.of<AddPizzaBloc>(context);

关于dart - 正在重新创建 Flutter BLoC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54523971/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com