Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dart 正在重建的颤振集团_Dart_Flutter_Bloc - Fatal编程技术网

Dart 正在重建的颤振集团

Dart 正在重建的颤振集团,dart,flutter,bloc,Dart,Flutter,Bloc,我正在探索颤振和团块模式,为了练习,我正在制作一个关于比萨饼的应用程序 我正在使用BlocProvider访问块。这是包装上的。它是一个基本的实现,使用InheritedWidget与无状态widget相结合 我有一个带有两个可编辑文本字段的页面,用于我想要创建的比萨饼的名称和价格。它由一个集团支持 代码如下: AddPizzaPage.dart: class AddPizzaPage extends StatelessWidget { @override Widget build(Bu

我正在探索颤振和团块模式,为了练习,我正在制作一个关于比萨饼的应用程序

我正在使用
BlocProvider
访问块。这是包装上的。它是一个基本的实现,使用
InheritedWidget
无状态widget
相结合

我有一个带有两个可编辑文本字段的页面,用于我想要创建的比萨饼的名称和价格。它由一个集团支持

代码如下:

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(),
      ),
    );
  }
}
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();
            },
          )
        ],
      ),
    );
  }
}
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);
    }
  }
}
列表页。省道:

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(),
      ),
    );
  }
}
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();
            },
          )
        ],
      ),
    );
  }
}
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);
    }
  }
}
class ModifyPizzaWidget扩展了无状态widget{
@凌驾
小部件构建(构建上下文){
最终添加pizzabloc=BlocProvider.of


我不知道如何使用bloc为addPizza表单供电。

发生这种情况是因为您正在使用build方法创建bloc的实例:

BlocProvider(
  bloc: Bloc(),
  child: ...
)
其结果是,任何重建都不会重用以前的实例(也有一些可怕的内存泄漏)

解决方案是创建一个
StatefulWidget
,并在
initState
中创建该BLoC实例,然后执行
dispose
覆盖以清理内容

但是既然你已经在使用一个软件包,你可以用它来代替。它是一个流行的替代品,可以完成上面列出的所有事情

因此,您的
BlocProvider
使用变得:

StatefulProvider(
   valueBuilder: (_) =>  AddPizzaBloc(),
   dispose: (_, bloc) => bloc.dispose(),
   child: // ...
),
然后获得如下结果:

Provider.of<AddPizzaBloc>(context);
Provider.of(上下文);

我同意,为了完成回答,即使AddPizzaPage是一个无状态小部件,颤振框架也会在虚拟键盘在屏幕上显示和隐藏时重建此小部件。如果您不想使用Statefull小部件,其他选项(但不是最好的)是在类构造函数中创建bloc things,但您将无法关闭流s不再需要时导致泄漏。我发誓我本周查找了提供程序包,当时没有StatefulProvider!感谢您的帮助。@Yutsa您需要使用提供程序而不是StatefulProvider,因为它们合并在一起了