Как синхронизировать Flutter TextField с полем Firestore? - PullRequest
0 голосов
/ 22 сентября 2018

У меня есть task документ в Firestore с полем todo и TextField в пользовательском интерфейсе флаттера.

Посоветуйте, пожалуйста, как синхронизировать textfield с полем todo, т. е.

  1. В любое время текст в textfield изменяется при вводе пользователем, обновите поле todo только что введенным значением.
  2. В любое время, todo поле обновлено (вручную в консоли Firestore или другим пользователем), обновите textfield с самым последним значением.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Прежде всего, поставьте TextEditingController на TextField (посмотрите на this для полного примера).

Для первой части вопроса вынужно будет предоставить listener до TextEditingController.Это listener должно вызывать такую ​​функцию:

  Future<void> _updateTaskValue(String text) {
    Firestore().runTransaction((Transaction transaction) {
      Firestore.instance.document([PATH OF YOUR DOCUMENT]).updateData({"todo": text});
    });
  }

Предполагая, что text является значением text контроллера.Обратите внимание, что runTransaction используется, чтобы избежать параллелизма данных.

Во второй части вопроса вам нужно будет прослушать документ.Для этого объявите в initState a StreamSubscription:

subscription = Firestore.instance.document("").snapshots().listen(
    (DocumentSnapshot snapshot) => this._onDatabaseUpdate(snapshot));

Эта подписка будет вызывать функцию при каждом обновлении контента (обновляет ли текущий пользователь TextField, другой пользователь обновляет его).или вручную из бэк-офиса).

Вызванная ниже функция просто обновляет атрибут контроллера text новым содержимым:

void _onDatabaseUpdate(DocumentSnapshot snapshot) {
  setState(() {
    _controller.text = snapshot.data["todo"];
  });
}

Полный пример см. это суть .

0 голосов
/ 24 сентября 2018
  1. TextField onChanged обновляет значение в firebase.
  2. Прослушивает изменение значения в firebase и обновляет значение для TextField с TextEditingController.

Вот код:

import 'dart:async';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'TODO Screen',
      theme: ThemeData(
        primarySwatch: Colors.orange,
      ),
      home: TODOScreen(),
    );
  }
}

class TODOScreen extends StatefulWidget {
  @override
  _TODOScreenState createState() => _TODOScreenState();
}

class _TODOScreenState extends State<TODOScreen> {
  final _ref = FirebaseDatabase.instance.reference().child('todo_id').child('value');
  TextEditingController _todoController = new TextEditingController();

  StreamSubscription _subscription;

  @override
  void initState() {
    super.initState();
    _subscription = _ref.onValue.listen((data) {
      String value = data.snapshot.value as String ?? "";
      updateOnChanged(value);
    });
  }

  saveOnChanged(String value) async {
    await _ref.set(value);
  }

  updateOnChanged(String value) async {
    setState(() {
      _todoController.value = _todoController.value.copyWith(
        text: value,
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('TODO Screen'),
      ),
      body: Center(
        child: Container(
          padding: EdgeInsets.all(10.0),
          child: TextField(
            decoration: InputDecoration(labelText: "TODO"),
            maxLines: 5,
            onChanged: saveOnChanged,
            controller: _todoController,
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _todoController.dispose();

    if (_subscription != null) _subscription.cancel();

    super.dispose();
  }
}

Надеюсь, что hepls!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...