Как получить указанный документ c в пожарном депо с флаттером - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь получить документ пожарного депо в моем приложении, чтобы я мог его обновить. Вот текущий код:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Baby Names',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() {
    return _MyHomePageState();
  }
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Baby Name Votes')),
      body: _buildBody(context),
    );
  }

  Widget _buildBody(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection('baby').snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) return LinearProgressIndicator();

        return _buildList(context, snapshot.data.documents);
      },
    );
  }

  Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
    return ListView(
      padding: const EdgeInsets.only(top: 20.0),
      children: snapshot.map((data) => _buildListItem(context, data)).toList(),
    );
  }

  Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
    final record = Record.fromSnapshot(data);
    final docID = record.reference.documentID;

    return Padding(
      key: ValueKey(record.name),
      padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
      child: Container(
        decoration: BoxDecoration(
          border: Border.all(color: Colors.grey),
          borderRadius: BorderRadius.circular(5.0),
        ),
        child: ListTile(
          title: Text(record.name),
          trailing: Text(record.votes.toString()),
          onTap: () {
            print('Here is the record you have just clicked on: $docID, ${record.name}, ${record.votes}');
            showModalBottomSheet(
              context: context,
              builder: (context) => EditVoteScreen(),
            );
          },
        ),
      ),
    );
  }
}

class EditVoteScreen extends StatefulWidget {
  @override
  _EditVoteScreenState createState() => _EditVoteScreenState();
}

class _EditVoteScreenState extends State<EditVoteScreen> {
  String newBabyName = 'Gregg';

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Color(0xff757575),
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.only(
              topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0)),
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Edit A Baby Name'),
            SizedBox(height: 20.0),
            Text(
              'Current Name: ${record.name}',
            ),
            SizedBox(height: 20.0),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'Change Baby Name To:',
                ),
                SizedBox(
                  width: 20.0,
                ),
                DropdownButton<String>(
                  value: newBabyName,
                  icon: Icon(Icons.arrow_drop_down_circle),
                  iconSize: 24,
                  elevation: 16,
                  underline: Container(
                    height: 1,
                    color: Color(0xFF150A42),
                  ),
                  onChanged: (String newValue) {
                    setState(() {
                      newBabyName = newValue;
                    });
                  },
                  items: <String>['Gregg', 'Mikey', 'Joey', 'Dave']
                      .map<DropdownMenuItem<String>>((String value) {
                    return DropdownMenuItem<String>(
                      value: value,
                      child: Text(value),
                    );
                  }).toList(),
                ),
              ],
            ),
            SizedBox(height: 20.0),
            FlatButton(
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15.0)),
              color: Color(0xFF150A42),
              textColor: Colors.white,
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 12.0),
                child: Text(
                  '?  Save Changes',
                ),
              ),
              onPressed: () {},
            ),
          ],
        ),
      ),
    );
  }
}

class Record {
  final String name;
  final int votes;
  final DocumentReference reference;

  Record.fromMap(Map<String, dynamic> map, {this.reference})
      : assert(map['name'] != null),
        assert(map['votes'] != null),
        name = map['name'],
        votes = map['votes'];

  Record.fromSnapshot(DocumentSnapshot snapshot)
      : this.fromMap(snapshot.data, reference: snapshot.reference);

  @override
  String toString() => "Record<$name:$votes>";
}

База данных пожарного магазина имеет только два поля. Вот некоторые примеры данных: имя: 'Джеймс' (строка), и голосов: 2 (число)

Когда вы нажимаете на запись в приложении, я Мне удалось заставить его распечатать docID в консоли, а также имя и голоса. Вопрос в том, как я могу взять документ, на котором я только что щелкнул, и отобразить его в ModalBottomSheet, чтобы можно было обновить поле имени?

Если я смогу отобразить его в поле имени в ModalBottomSheet, я должен быть в состоянии выяснить, как обновить его самостоятельно. Но я изо всех сил пытаюсь заставить это появляться там! Мой текущий код отображает ошибку undefined name 'record'.

Любая помощь будет принята с благодарностью!

Спасибо

Джейсон

1 Ответ

1 голос
/ 22 апреля 2020

Вам нужно добавить конструктор в ваш виджет EditVoteScreen и передать информацию документа, чтобы вы могли использовать ее в методе сборки вашего EditVoteScreen:

class EditVoteScreen extends StatefulWidget {
  final Record record;
  const EditVoteScreen({Key key, this.record}) : super(key: key); 
  @override
  _EditVoteScreenState createState() => _EditVoteScreenState();
}

Передать запись при создании класса:

showModalBottomSheet(
    context: context,
    builder: (context) => EditVoteScreen(record: record,),
);

Затем ссылайтесь на него в классе состояний, ссылаясь на переменную виджета.

child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Edit A Baby Name'),
            SizedBox(height: 20.0),
            Text(
              'Current Name: ${widget.record.name}', // Here
            ),
...