firebase - 在 Streambuilder 中使用 TextField
问题描述
我们如何在 StreamBuilder 中添加 TextField?我有一个 TextField / TextFormField 作为 StreamBuilder 或 FutureBuilder 的构建器函数内的小部件之一,每当我们尝试与文本字段交互时,它只会刷新整个构建器小部件并再次调用流/未来。
body: StreamBuilder(
stream: getClientProfile().snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
print(snapshot.data.data);
Client tempClient = Client.from(snapshot.data);
print('details = ${tempClient.representative.email} ${tempClient
.address.location} ${tempClient.businessDescription}');
return Container(
child: Column(
children: <Widget>[
TextFormField(
)
],
),
);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else {
return Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.error),
),
Text('Error loading data')
],
),
);
}
}),
和火库功能
DocumentReference getClientProfile() {
return _firestore.collection(SELLERS_COLLECTION).document(_uid);
}
我想要实现的是从firestore文档中获得一个带有预填充数据的表单,基本上是一个编辑表单。有没有其他方法可以达到同样的效果,或者我在结构上做错了什么?
编辑:
建议编辑后的代码。
import 'package:flutter/material.dart';
import 'Utils/globalStore.dart';
import 'models/client_model.dart';
import 'dart:async';
class EditProfileInformation extends StatefulWidget {
@override
EditProfileInformationState createState() {
return new EditProfileInformationState();
}
}
class EditProfileInformationState extends State<EditProfileInformation> {
Stream dbCall;
final myController = TextEditingController();
@override
void initState() {
// TODO: implement initState
super.initState();
dbCall = getClientProfile().snapshots();
myController.addListener(_printLatestValue);
}
_printLatestValue() {
print("Second text field: ${myController.text}");
}
@override
void dispose() {
myController.removeListener(_printLatestValue);
myController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
// key: _scaffoldKey,
appBar: AppBar(
title: Text(
'Edit profile',
style: TextStyle(),
),
),
body: StreamBuilder(
stream: dbCall,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
print(snapshot.data.data);
Client tempClient = Client.from(snapshot.data);
print('details = ${tempClient.representative.email} ${tempClient
.address.location} ${tempClient.businessDescription}');
return Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: myController,
),
)
],
),
);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else {
return Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.error),
),
Text('Error loading data')
],
),
);
}
}),
floatingActionButton: FloatingActionButton(
onPressed: () {
},
child: Icon(Icons.done),
),
);
}
}
解决方案
为了正确使用 StreamBuilder,您必须确保您正在使用的流缓存在 State 对象上。虽然 StreamBuilder 可以正确处理从流中获取新事件,但接收全新的 Stream 将强制它完全重建。在您的情况下,getClientProfile().snapshots()
将在调用时创建一个全新的 Stream ,从而破坏文本字段的所有状态。
class Example extends StatefulWidget {
@override
State createState() => new ExampleState();
}
class ExampleState extends State<Example> {
Stream<SomeType> _stream;
@override
void initState() {
// Only create the stream once
_stream = _firestore.collection(collection).document(id);
super.initState();
}
@override
Widget build(BuildContext context) {
return new StreamBuilder(
stream: _stream,
builder: (context, snapshot) {
...
},
);
}
}
编辑:听起来我无法从您提供的代码片段中诊断出其他问题。
推荐阅读
- youtube - Youtube API getCurrentTime() 以毫秒为单位?
- java - 没有类型声明的 Map.Entry
- visual-studio - 为什么我连接到远程服务器时找不到项目的进程?
- php - 如何在 Windows 中通过 CLI 将 php 5.4 更新到 7.0
- android - 升级到 com.google.android.material:material:1.1.0 时是否还有其他人出现错误?
- python - Python Zeep AttributeError:“NoneType”对象没有属性“元素”[切换到 suds-community]
- python - 我在点击隐藏元素时遇到问题
- html - 某些图像不会出现在浏览器中
- windows - Traefik:v2 Windows Container 无法检索 docker 客户端和服务器主机的信息
- swift - Mapbox 如何在 MGLPolygonFeature 上设置填充颜色(或添加要素属性)