web-dev-qa-db-fra.com

comment accéder à un objet créé dans un widget avec état dans un autre widget avec état dans flutter

Je suis coincé dans mon projet où j'ai deux widgets avec état créés en flutter comme deux fichiers Dart différents. Maintenant, je dois accéder à l'instance d'un objet créé dans le premier widget dans le deuxième widget, mais je ne sais pas trop comment je peux le faire en flottant lors de la création de widgets.

Une solution possible à laquelle j'ai pensé est de déclarer les deux widgets dans un seul fichier Dart au lieu de deux fichiers Dart pour deux dispositions, mais je suis curieux de savoir si nous pouvons le faire en déclarant dans deux fichiers Dart distincts.

J'ai publié les fichiers juste pour recréer le problème.

main.Dart

 import 'package:flutter/material.Dart';
 import 'package:untitled2/models.Dart';
 import 'package:untitled2/secondwidget.Dart';

void main() {
 runApp(new MaterialApp(
     home: new MyApp(),
 ),);
}

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
  }

      class _MyAppState extends State<MyApp> {
 final TextEditingController _nameController = new TextEditingController();
 final TextEditingController _emailIdController = new 
 TextEditingController();
 final TextEditingController _passwordController = new 
 TextEditingController();
 final TextEditingController _confirmPasswordController = new 
 TextEditingController();

 MyModel myModel = new MyModel();

 @override
 Widget build(BuildContext context) {
  return new MaterialApp(
  home: new Scaffold(
    body: new ListView(

      children: <Widget>[
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
              labelText: 'Enter your Name'
            ),
            controller: _nameController,
            onSaved: (String value){myModel.name = value;} ,
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'EmailId'
            ),
              controller: _emailIdController,
              onSaved: (String value){myModel.emailId = value;}
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Password'
            ),
              controller: _passwordController,
              onSaved: (String value){myModel.password = value;}
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Confirm Password'
            ),
            controller: _confirmPasswordController,

          ),
        ),
        new Container(
          child: new FlatButton(
            onPressed: ((){

              Navigator.Push(context, new MaterialPageRoute(builder: (_) => 
         new SecondScreen(),),);

            }),
            child: new Text('Save'),),
        ),



      ],


      ),
     ),
    );
   }
  }

models.Dart

class MyModel {

String name;
String emailId;
String password;

  }

secondwidget.Dart

 import 'package:flutter/material.Dart';


 class SecondScreen extends StatefulWidget {
 @override
 _SecondScreenState createState() => new _SecondScreenState();
}

class _SecondScreenState extends State<SecondScreen> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
  home: new Scaffold(
    body: new ListView(

      children: <Widget>[
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Enter address'
            ),
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Address Line 2'
            ),
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Address Line 3'
            ),
          ),
        ),
        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'POST CODE'
            ),
          ),
        ),

        new Container(
          child: new TextFormField(
            decoration: new InputDecoration(
                labelText: 'Mobile Number'
            ),
          ),
        ),
        new Container(
          child: new FlatButton(
              onPressed: ((){


                //I want to Push the data captured from main.Dart and from 
                            //secondwidget.Dart into database
     // I want to use the instance of MyModel from main.Dart here to save 
      // the data captured from the first screen and this one into database

              }),
              child: new Text('Save'),),
        ),


      ],


    ),
  ),
);
}
}
16
Mahi

Il existe de nombreuses façons de procéder en fonction de votre cas d'utilisation. Voici quelques options:

  1. Vous pouvez exposer l'objet créé en tant que membre public de votre State. Utilisez ensuite la propriété currentState d'un GlobalKey dans un State pour obtenir une référence à l'autre State. Vous pouvez maintenant accéder à l'objet créé via le membre public. (Remarque: ce modèle limite la testabilité et l'encapsulation de votre State, alors utilisez-le avec parcimonie.)
  2. Les deux widgets peuvent avoir un widget ancêtre qui étend InheritedWidget qu'ils utilisent pour rechercher l'objet créé.
  3. Les deux widgets peuvent recevoir un argument de modèle dans leur constructeur a, tel que ValueNotifier . Ils peuvent utiliser cet objet pour lire et écrire la valeur.

Si vous allez plus en détail sur votre cas d'utilisation, nous pouvons vous aider à choisir un modèle qui a du sens.

Voici quelques options d'implémentation de code # 1.

import 'package:flutter/material.Dart';

void main() {
  runApp(new MyApp());
}

final key = new GlobalKey<MyStatefulWidget1State>();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        body: new Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            new MyStatefulWidget1(key: key),
            new MyStatefulWidget2(),
          ],
        ),
      ),
    );
  }
}

class MyStatefulWidget1 extends StatefulWidget {
  MyStatefulWidget1({ Key key }) : super(key: key);
  State createState() => new MyStatefulWidget1State();
}

class MyStatefulWidget1State extends State<MyStatefulWidget1> {
  String _createdObject = "Hello world!";
  String get createdObject => _createdObject;

  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new Text(_createdObject),
    );
  }
}

class MyStatefulWidget2 extends StatefulWidget {
  State createState() => new MyStatefulWidget2State();
}

class MyStatefulWidget2State extends State<MyStatefulWidget2> {
  String _text = 'PRESS ME';

  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new RaisedButton(
        child: new Text(_text),
        onPressed: () {
          setState(() {
            _text = key.currentState.createdObject;
          });
        },
      ),
    );
  }
}
35
Collin Jackson

Vous pouvez transmettre le modèle lorsque vous construisez le widget SecondScreen.

  1. Ajouter un modèle au constructeur SecondScreen:

    class SecondScreen extends StatefulWidget {
      final MyModel myModel;
    
      SecondScreen(MyModel myModel, {Key key}):
          super(key: key);
    ...
    }
    
  2. Passez le modèle lorsque vous construisez SecondScreen dans main.Dart

    Navigator.Push(context, new MaterialPageRoute(builder: (_) => 
      new SecondScreen(model)));
    
  3. Vous pouvez maintenant accéder au modèle dans _SecondScreenState via widget.myModel

8
aptik