StreamBuilder का उपयोग करके TextField के लिए मूल्य कैसे अपडेट करें?


13

मेरे पास एक है textfieldऔर मैं sqfliteअपने ऐप में डेटाबेस का उपयोग कर रहा हूं। sqfliteएक मूल्य जो मैं करने के लिए आवंटित करने के लिए की जरूरत है मेरीtextfield

यहाँ मेरा textfieldकोड है

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

अब initstateमेरी कक्षा की विधि में, मैं डेटाबेस से मूल्य प्राप्त कर रहा हूं। यह एक अतुल्यकालिक ऑपरेशन है इसलिए इसमें समय लगता है।

मेरी ब्लॉक क्लास का कोड इस प्रकार है

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

इसलिए जैसे ही मुझे डेटाबेस से मूल्य प्राप्त होता है, मैं उसके बाद कॉल करता हूं

doctorNameChanged("valuefromdatabase");

लेकिन मैं अपने टेक्स्टफील्ड में मूल्य नहीं देख सकता। इसके अलावा मेरे डेटाबेस में एक मान मौजूद है। क्या इसका उपयोग किए बिना मूल्य को अपडेट करना संभव है TextEditingControllerया नहीं setState। मैं के रूप में मेरी कक्षा chuncks और जिस तरह से भी के किसी भी उपयोग करने के लिए ऊपर मैं के साथ एक ही दृष्टिकोण का उपयोग कर की कोशिश की है जटिल की बहुत में विभाजित किया गया है उन से बचने की कोशिश मा RadioButtonऔर CheckBoxऔर वे ठीक से अद्यतन करने के लिए लग रहे हैं। मान भी अद्यतन किया गया है _doctorName.stream.valueजिसमें डेटाबेस में मौजूद है, लेकिन textfieldकोई डेटा नहीं दिखाता है। इसके अलावा मैंने कोशिश की रंग बदलने की textfieldतो वहाँ कोई समस्या नहीं है और साथ ही मैं यह देखने में सक्षम हूँ कि मैं क्या टाइप करता हूँ।

मैंने ऐप का एक छोटा सा डेमो बनाया है https://github.com/PritishSawant/demo/tree/master/lib

उपयोग करने के बजाय sqflite, मैं उपयोग कर रहा हूं shared preferencesलेकिन समस्या बनी रहती है


निकालने का प्रयास करें "initialValue: patientHealthFormBloc.doctorNameValue", और StreamBuilder से "initialData" में इसे शुरू
Stel

@Stel धन्यवाद नहीं बल्कि काम करता है
Nudge

आप TextEditingController (पाठ

@ChinkySight मैं TextEditingController से बचने के लिए स्ट्रीम का उपयोग कर रहा हूं। एप्लिकेशन जटिल है और TextEditingController का उपयोग कर संभव नहीं है
Nudge

आपके उदाहरण में आप स्नैपशॉट का उपयोग बिल्कुल नहीं कर रहे हैं। अपने TextFormField में उपयोग करने के लिए आप इससे कौन सा डेटा निकालने की अपेक्षा करते हैं? आप TextEditingController का उपयोग क्यों नहीं कर सकते हैं?
जोआ सोरेस

जवाबों:


4

ठीक है तो मैंने आखिरकार अपनी समस्या का हल ढूंढ लिया।

निम्नलिखित मेरा कोड है, मैंने नीचे दिए उदाहरण के SharedPreferencesबजाय इसका उपयोग sqfliteकिया है। कुछ भी किया जा सकता हैsqflite

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);
              },
            );
           },
        ),
      ),
    );
  }
}

यह एक बहुत अधिक इंजीनियर समाधान है। काश आपने समझाया होता कि वास्तव में आप अपने विशिष्ट समाधान को ठीक करने के लिए क्या चाहते थे, बजाय इसके कि आप मूल रूप से हासिल करना चाहते हैं। जैसा कि मैंने आपके प्रश्न पर टिप्पणी की थी, आप टेक्स्टफ़िल्ड को वास्तविक समय अपडेट करने की इच्छा रखते हैं जो उपयोगकर्ता द्वारा सक्रिय रूप से उपयोग किया जा सकता है। यह बहुत अजीब और संभावना है कि बुरा UX है।
जोआ सोरेस

@ JoãoSoares क्या आप अपना समाधान पोस्ट कर सकते हैं। मैं इनाम देने से ज्यादा खुश हूं और अगर आपके लिए यह मेरे से बेहतर है तो अपने समाधान को स्वीकार करें। मैंने अभी एक आसान समाधान पोस्ट किया है, ताकि सभी लोग समझ सकें लेकिन वास्तव में मेरे ऐप को sqflite के साथ-साथ फायरस्टार के साथ सिंक करने की आवश्यकता है ताकि यह आपको इंजीनियर लग सके
Nudge

यदि आप बता सकते हैं कि आप उसी समय TextFieldForm के मूल्य को अपडेट (अपडेट) क्यों करना चाहते हैं, तो उपयोगकर्ता इसका उपयोग कर सकता है, मैं आपकी मदद करने में सक्षम हो सकता हूं। SQFlite और Firestore के साथ समन्वय करने से मेरे दावे में कोई भागीदारी नहीं है कि आपने जो समाधान प्रस्तुत किया है वह अति-इंजीनियर है।
जोहो सरेस

@ JoãoSoares कृपया प्रश्न को फिर से पढ़ें।
नजगे

मैंने पहले ही प्रश्न को कई बार पढ़ा है और आपने GitHub पर साझा किए गए कोड को देखा है। आपका स्पष्टीकरण बोलता है कि आप क्या करना चाहते हैं और आप कैसे लिखा कोड चाहते हैं। यह व्याख्या नहीं करता है कि आप क्यों चाहते हैं कि TextFormField उस तरह से डेटा स्ट्रीमिंग या उस व्यवहार के आधार के साथ भरा हो।
जोहो सोरास

2

निम्नलिखित दृष्टिकोण का प्रयास करें:

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);
      },
    ...

यदि आपको और अधिक मदद की ज़रूरत है तो मुझे बताएं।


काम नहीं करता है ...
Nudge

क्या आप स्ट्रीम में नए नाम प्राप्त कर रहे हैं?
हर्षवर्धन जोशी

हाँ, लेकिन मान अपडेट किया जा रहा है नहीं है
Nudge

क्या आप एक ही नए नाम प्राप्त कर रहे हैं builder: (context, snapshot)?
हर्षवर्धन जोशी

जब मैं एक पाठ टाइप करता हूं, तो मुझे टाइप किया गया पाठ प्राप्त होता है। प्रारंभिक चरण में जब मैं db से प्राप्त कर रहा हूं तब यह db मान को प्रिंट कर रहा है। स्ट्रीमब्यूलर ठीक काम कर रहा है और जब मैं मैन्युअल रूप से टाइप करता हूं तो मान अपडेट होता है, लेकिन जब डेटाबेस से इसे लाया जाता है तो यह अपडेट नहीं होता है
Nudge

1

मेरी टिप्पणियों में जो सुझाव दे रहा था वह कुछ इस तरह था:

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);
        },
      ],
    ),
  );
}

मैं इस उत्तर को यह समझे बिना लिखना नहीं चाहता था कि आप टेक्स्टएडिटिंगकंट्रोलर या सेटस्टेट का उपयोग क्यों नहीं करना चाहते हैं। लेकिन यह हासिल करना चाहिए कि ब्लाक पैटर्न का उपयोग करते समय आप क्या चाहते हैं।


मैंने शुरुआत में यह सोचा था, लेकिन चूंकि प्रश्न उद्धृत किया गया था और @Nudge उपयोग नहीं करने पर जोर दे TextEditControllerरहा था , इसलिए मैंने उस आइडिया को स्क्रैप कर दिया। यह बहुत अच्छा है कि केवल नियंत्रक का उपयोग करने से समाधान सरल और छोटा हो जाता है सटीक रूप से काम करने के लिए। अच्छा काम।
हर्षवर्धन जोशी

1
धन्यवाद मैं इसकी सराहना करता हूँ। दुर्भाग्य से उपयोगकर्ता अपने स्वयं के विचार से चिपके रहने और उचित समाधान लिखने का प्रयास नहीं कर रहा था, जैसे कि उन्होंने सही प्रतिक्रिया या इनाम की विशेषता का फैसला नहीं किया।
जोआ सोरेस

ओह ठीक है। तो कोई बात नहीं।
हर्षवर्धन जोशी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.