ভিউমোডেল থেকে লাইভ ডেটা পর্যবেক্ষণ


95

আমার একটি পৃথক শ্রেণি রয়েছে যার মধ্যে আমি ডেটা আনার ব্যবস্থা করি (বিশেষত ফায়ারবেস) এবং আমি সাধারণত এটি থেকে লাইভ ডেটা অবজেক্টগুলি ফিরিয়ে আনি এবং সংযোজিতভাবে আপডেট করি। এখন আমি ফিরিয়ে নেওয়া ডেটা ভিউমোডেলে সংরক্ষণ করতে চাই, তবে সমস্যাটি হ'ল মানটি পেতে, আমার ডেটা আনার ক্লাস থেকে ফিরে আসা লাইভডেটা অবজেক্টটি পর্যবেক্ষণ করা দরকার। পর্যবেক্ষণ পদ্ধতির জন্য প্রথম প্যারামিটার হিসাবে একটি লাইফসাইকেলউইনর অবজেক্টের প্রয়োজন ছিল, তবে আমার স্পষ্টতই আমার ভিউমোডেলের অভ্যন্তর নেই এবং আমি জানি যে ভিউমোডেলের অভ্যন্তরে ক্রিয়াকলাপ / খণ্ডের কোনও রেফারেন্স রাখার কথা নয়। আমার কি করা উচিৎ?


উত্তর:


39

ইন এই ব্লগ পোস্টে Google বিকাশকারীর জোসে Alcérreca দ্বারা এটি এই ক্ষেত্রে একটি রূপান্তর ব্যবহার করতে ( "সংগ্রহস্থলগুলিতে LiveData" প্যারা দেখুন) কারণ বাঞ্ছনীয় ViewModel এর সাথে সম্পর্কিত কোন রেফারেন্স রাখা উচিত নয় View(কার্যকলাপ, কনটেক্সট ইত্যাদি) করা হয়েছে কারণ এটি এটি হার্ড তৈরি পরীক্ষা করা।


আপনি কি আপনার জন্য ট্রান্সফর্মেশন কাজ করতে পেরেছেন? আমার ইভেন্টগুলি কাজ করছে না
রোমানেসো

26
নিজের রূপান্তরগুলি কাজ করে না, যেহেতু আপনি রূপান্তরে যে কোডই লিখুন কেবল তখনই সংযুক্ত থাকে যখন কোনও সত্তা রূপান্তরটি পর্যবেক্ষণ করে
অরবিটবট

9
আমি জানি না কেন এটি প্রস্তাবিত উত্তর, প্রশ্নের সাথে এর কোনও যোগসূত্র নেই। 2 বছর পরে, এবং আমরা এখনও আমাদের ভিউ মডেলগুলিতে কীভাবে সংগ্রহস্থলের ডেটা পরিবর্তনগুলি পর্যবেক্ষণ করতে পারি তা জানি না।
অ্যান্ড্রু

26

ইন ViewModel ডকুমেন্টেশন

তবে ভিউমোডেল অবজেক্টগুলি কখনই লাইফডাইকা অবজেক্টের মতো জীবনচক্র সচেতন পর্যবেক্ষণে পরিবর্তনগুলি পর্যবেক্ষণ করে না।

আর একটি উপায় হ'ল ডেটা লাইভডাটার পরিবর্তে আরএক্সজেভা প্রয়োগ করা, তারপরে এটির জীবনচক্র সচেতন হওয়ার সুবিধা থাকবে না।

টোডো-এমভিভিএম-লাইভ-কোটলিনের গুগল নমুনায় এটি ভিউমোডেলে লাইভ ডেটা ছাড়াই কলব্যাক ব্যবহার করে।

আমি অনুমান করছি আপনি যদি লাইফাইসাইকেল-ওয়্যার হওয়ার পুরো ধারণাটি মেনে চলতে চান তবে আমাদের ক্রিয়াকলাপ / খণ্ডে পর্যবেক্ষণের কোডটি সরানো দরকার। অন্যথায়, আমরা ভিউমোডেলে কলব্যাক বা আরএক্সজাভা ব্যবহার করতে পারি।

আর একটি আপস হ'ল মেডিট্রেটিভ লাইভ ডেটা (বা ট্রান্সফরমেশন) বাস্তবায়ন করা এবং ভিউমোডেলে পর্যবেক্ষণ করুন (আপনার যুক্তি এখানে রাখুন)। লক্ষ্য করুন মধ্যস্থতাজীবীতা ডেটা পর্যবেক্ষক ক্রিয়াকলাপ / খণ্ডের মধ্যে পর্যবেক্ষণ করা না হলে (ট্রান্সফরমেশনগুলির সমান) ট্রিগার করবে না। আমরা যা করি তা হ'ল আমরা ক্রিয়াকলাপ / খণ্ডগুলিতে একটি ফাঁকা পর্যবেক্ষণ রাখি, যেখানে আসল কাজটি আসলে ভিউমোডেলে করা হয়।

// ViewModel
fun start(id : Long) : LiveData<User>? {
    val liveData = MediatorLiveData<User>()
    liveData.addSource(dataSource.getById(id), Observer {
        if (it != null) {
            // put your logic here
        }
    })
}

// Activity/Fragment
viewModel.start(id)?.observe(this, Observer {
    // blank observe here
})

পিএস: আমি ভিউমোডেলস এবং লাইভডেটা পড়ি: প্যাটার্নস + অ্যান্টিপ্যাটার্নগুলি যা প্রস্তাবিত যে রূপান্তরগুলি। লাইভ ডেটা পর্যবেক্ষণ না করা (এটি সম্ভবত ক্রিয়াকলাপ / খণ্ডে করা দরকার) যদি না হয় তবে এটি কাজ করে বলে আমি মনে করি না।


4
এক্ষেত্রে কি কিছু পরিবর্তন হয়েছে? অথবা আরএক্স, কলব্যাক বা ফাঁকা পর্যবেক্ষণ কেবল সমাধান?
কিবাইট

4
এই ফাঁকা থেকে মুক্তি পেতে কোন সমাধান পর্যবেক্ষণ করে?
এহসান মাশহাদি

4
হতে পারে ফ্লো ( mLiveData.asFlow()) বা ব্যবহার করে observeForever
মাচাডো


14

আমি মনে করি আপনি অবজার্ভফোরভারটি ব্যবহার করতে পারেন যার জন্য লাইফসাইকেলের মালিকের ইন্টারফেসের প্রয়োজন হয় না এবং আপনি ভিউ মডেল থেকে ফলাফলগুলি পর্যবেক্ষণ করতে পারেন


4
এটি আমার কাছে সঠিক উত্তর বলে মনে হচ্ছে বিশেষত ViewModel.onCleared () সম্পর্কে ডক্সে বলা হয়েছে: "ভিউমোডেল কিছু ডেটা পর্যবেক্ষণ করে এবং এই ভিউমোডেলের ফাঁস রোধ করতে আপনার এই সাবস্ক্রিপশনটি সাফ করা দরকার।"
ইউসুফ

4
দুঃখিত তবেCannot invoke observeForever on a background thread
বোকেন

4
এটি বেশ বৈধ বলে মনে হচ্ছে। যদিও একটিকে ভিউমোডেল ক্ষেত্রগুলিতে পর্যবেক্ষকগুলি সংরক্ষণ করতে হবে এবং এতে সাবস্ক্রাইব করতে হবে onCleared। ব্যাকগ্রাউন্ড থ্রেড হিসাবে - মূল থ্রেড থেকে পর্যবেক্ষণ করুন, এটিই।
কিরিল স্টারোস্টিন

@Boken আপনি জোর করতে পারেন observeForeverমাধ্যমে প্রধান থেকে প্রার্থনা করাGlobalScope.launch(Dispatchers.Main) { myvm.observeForever() }
rmirabelle

5

আর্কিটেকচার উপাদানগুলির সাথে কোটলিন কর্টিনগুলি ব্যবহার করুন।

liveDataফলসটিকে suspendকোনও LiveDataবস্তু হিসাবে পরিবেশন করে আপনি কোনও ফাংশন কল করতে বিল্ডার ফাংশনটি ব্যবহার করতে পারেন ।

val user: LiveData<User> = liveData {
    val data = database.loadUser() // loadUser is a suspend function.
    emit(data)
}

আপনি ব্লক থেকে একাধিক মান নির্গত করতে পারেন। প্রতিটি emit()কলটি LiveDataমূল থ্রেডে মান সেট না করা অবধি ব্লকের কার্য সম্পাদন স্থগিত করে ।

val user: LiveData<Result> = liveData {
    emit(Result.loading())
    try {
        emit(Result.success(fetchUser()))
    } catch(ioException: Exception) {
        emit(Result.error(ioException))
    }
}

আপনার গ্রেড কনফিগারেশনে, ব্যবহার করুন androidx.lifecycle:lifecycle-livedata-ktx:2.2.0বা উচ্চতর।

এটি সম্পর্কে একটি নিবন্ধও রয়েছে

আপডেট : এছাড়াও এটি পরিবর্তন করতে সম্ভব LiveData<YourData>মধ্যে Dao interfacesuspendফাংশনে আপনার কীওয়ার্ডটি যুক্ত করতে হবে:

@Query("SELECT * FROM the_table")
suspend fun getAll(): List<YourData>

এবং ViewModelআপনার এটির মতো অতীব সঙ্কলিতভাবে এটি পাওয়া দরকার:

viewModelScope.launch(Dispatchers.IO) {
    allData = dao.getAll()
    // It's also possible to sync other data here
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.