StreamBuilder kullanarak TextField değerini nasıl güncelleyebilirim?


13

Ben bir textfieldve ben sqflitebenim app veritabanı kullanıyorum . sqfliteİ atamak gereken bir değere sahiptir benimtextfield

İşte textfieldkodum

 StreamBuilder<String>(
    stream: patientHealthFormBloc.doctorName,
    builder: (context, snapshot) {
      return TextFormField(
        initialValue: patientHealthFormBloc.doctorNameValue,
        onChanged: (value) {
          patientHealthFormBloc.doctorNameChanged(value);
        },
        ...

Şimdi initstatesınıf yönteminde, ben veritabanından değer getiriyorum. Zaman uyumsuz bir işlem olduğundan zaman alır.

Bloc sınıfımda aşağıdaki gibi bir kod var

Function(String) get doctorNameChanged => _doctorName.sink.add;

Ben veritabanından değer alır almaz ben aşağıdaki çağrı

doctorNameChanged("valuefromdatabase");

ama benim metin alanında değeri göremiyorum. Ayrıca veritabanımda bir değer var. O kullanmadan değerini güncellemek mümkün mü TextEditingControllerya setState. Benim sınıf çok ben aynı yaklaşımı kullanarak denedi yukarıdakilerden herhangi birini kullanmak için karmaşık chuncks ve yolun sürü bölünür sıra bu kaçınmaya çalışan ma RadioButtonve CheckBoxve bunların düzgün güncellemek gibi görünüyor. Değer, _doctorName.stream.valueveritabanında bulunan ancak textfieldveri göstermeyen de güncelleştirilir . Ayrıca ben textfieldorada hiçbir sorun var yanı sıra ben ne yazdığımı görmek mümkün olan renk değiştirmeye çalıştı .

Ben app küçük bir demo yaptım https://github.com/PritishSawant/demo/tree/master/lib

Kullanmak yerine sqflitekullanıyorum shared preferencesama sorun devam ediyor


"İnitialValue: hastaHealthFormBloc.doctorNameValue" dosyasını kaldırmayı deneyin ve StreamBuilder
Stel

@Stel Teşekkür ancak çalışır
Sıkışma

TextEditingController (text

@ChinkySight TextEditingController önlemek için Stream kullanıyorum. Uygulamanın karmaşık ve TextEditingController kullanılarak uygulanabilir değildir
Sıkışma

Örneğinizde anlık görüntüyü hiç kullanmıyorsunuz. TextFormField öğenizde kullanmak için hangi verileri çıkarmayı umuyorsunuz? Neden bir TextEditingController kullanamıyorsunuz?
João Soares

Yanıtlar:


4

Tamam bu yüzden sonunda benim sorunum için çözüm bulundu.

Aşağıdaki benim kod, ben sadece aşağıdaki örnek SharedPreferencesyerine kullandık . sqfliteAynı şey ile yapılabilirsqflite

class _MyHomePageState extends State<MyHomePage> {

  MyBloc myBloc = MyBloc();
  TextEditingController myController = TextEditingController();

  @override
  void dispose() {
    myBloc?.close();
    myController?.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    AppPreferences.setString("data", "this is my data");
    AppPreferences.getString("data").then((value){
      myBloc.dataChanged(value);
    });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder(
          stream: myBloc.data,
           builder: (context,snapshot){

            debugPrint(snapshot.data);
            myController.value = myController.value.copyWith(text: myBloc.dataValue);

            return TextFormField(
              controller: myController,
              onChanged: (value){
                myBloc.dataChanged(value);
              },
            );
           },
        ),
      ),
    );
  }
}

Bu aşırı mühendislik ürünü bir çözümdür. Size özel çözümünüzü düzeltmemizi istemek yerine, tam olarak ne elde etmek istediğinizi açıklasaydınız. Sorunuz hakkında yorum yaptığım gibi, bir TextField için kullanıcı tarafından aktif olarak kullanılabilecek gerçek zamanlı güncellemeler yapmak istiyor gibi görünüyorsunuz. Bu çok garip ve muhtemelen kötü bir UX.
João Soares

@ JoãoSoares Çözümünüzü gönderebilir misiniz? Ödül almaktan ve benimkinden daha iyi ise çözümünüzü kabul etmekten mutluluk duyuyorum. Herkesin anlayabilmesi için daha kolay bir çözüm yayınladım, ancak gerçekte uygulamam sqflite ve firestore ile senkronize edilmesini gerektiriyor, bu yüzden size göre tasarlanmış olabilir
Nudge

Neden bir TextFieldForm değerini aynı anda kullanıcı tarafından Akış (güncellemek) istediğinizi açıklayabilirseniz, size yardımcı olabilirim. SQFlite ve Firestore ile senkronize etmenin, sunduğunuz çözümün aşırı tasarlanmış olduğu iddiamla ilgisi yok.
João Soares

@ JoãoSoares Lütfen soruyu tekrar okuyun.
iteleme

Soruyu zaten birkaç kez okudum ve GitHub'da paylaştığınız kodu gördüm. Açıklamanız, ne yapmak istediğinizden ve kodun nasıl yazılmasını istediğinizden bahsediyor. Neden bir TextFormField veri akışı veya bu davranış için öncül ile bu şekilde doldurmak istediğiniz açıklamıyor.
João Soares

2

Aşağıdaki yaklaşımı deneyin:

StreamBuilder<String>(
  stream: patientHealthFormBloc.doctorName,
  builder: (context, snapshot) {
    String doctorName = patientHealthFormBloc.doctorNameValue;
    if(snapshot.hasData){
      doctorName = snapshot.data/*(your name string from the stream)*/;
    } 
    return TextFormField(
      initialValue: doctorName,
      onChanged: (value) {
        patientHealthFormBloc.doctorNameChanged(value);
      },
    ...

daha fazla yardıma ihtiyacınız olursa bana bildirin.


... çalışmıyor
Sıkışma

akışta yeni adlar alıyor musunuz?
Harshvardhan Joshi

evet ama değer güncellenmiyor
Nudge

içinde aynı yeni isimleri builder: (context, snapshot)mi alıyorsun ?
Harshvardhan Joshi

Bir metin yazdığımda, yazılan metni alıyorum. Ben db getirme ilk aşamada sonra db değerini yazdırıyor.A StreamBuilder el ile yazarken iyi çalışıyor ve değer güncellenir ancak veritabanından getirildiğinde güncelleştirilmez
Nudge

1

Benim yorumlarımda öneren şey şuydu:

TextEditingController _textEditingController = TextEditingController();

@override
void initState() {
  patientHealthFormBloc.doctorName.listen((snapshot){
    setState((){
      _textEditingController.text = snapshot;
    });
  });
  super.initState();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Column(
      children: <Widget>[
      TextFormField(
        controller: _textEditingController,
        onChanged: (value) {
          patientHealthFormBloc.doctorNameChanged(value);
        },
      ],
    ),
  );
}

Bu cevabı neden bir TextEditingController veya setState kullanmak istemediğinizi anlamadan yazmak istemedim. Ancak bu, Bloc desenini kullanırken istediğinizi elde etmelidir.


Başlangıçta bu düşünceye sahiptim, ama alıntılanan soru ve @Nudge kullanmama konusunda ısrar ettiğinden, TextEditControllerbu Fikri kazıdım . Sadece kontrolörü kullanarak çözümün doğru şekilde çalışması basit ve küçük hale gelmesi harika. İyi iş.
Harshvardhan Joshi

1
Teşekkür ederim, takdir ediyorum. Ne yazık ki, kullanıcı kendi fikrine sadık kalmaya ve uygun bir çözüm yazmaya kalkışmaya kararlı görünüyordu, çünkü doğru yanıtı veya ödülü atfetmemeye karar verdiler.
João Soares

Tamam. Boş ver o zaman.
Harshvardhan Joshi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.