ارسال چند ریکوئست و دریافت اونها به صورت جداگانه..

پرسیده شده
فعالیت 1145 روز پیش
دیده شده 787 بار
1

سلام خدمت استاد و دوستان گرامی.. 

 

استاد یه مبحثی رو گذاشتن برای تمرین که مثلا لیست پربازدیدترین هارو هم با همون یه متد بگیریم..

من این فانکشن رو نوشتم ولی مشکلی که داره اینه که میاد میبینه آخرین ریکوئست چیه و اون رو به لایو دیتا میده و لایو دیتا آخرین ریکوئست رو به ویو برمیگردونه چطوری میتونم بهش بگم تک به تک انجام بده کار رو؟ آیا باید برای هر یه لیست یه فانکشن جدا بنویسم با یه لایو دیتای جدا؟

 

فانکشن گرفتن لیست Product:

fun requestProductLists(sortId: Int): LiveData<List<Product>> {
        if ((sortId == SORT_LATEST) || (sortId == SORT_POPULAR) || (sortId == SORT_PRICE_DEC) || (sortId == SORT_PRICE_ASC)) {
            progressBarLiveData.value = true
            productRepository.getProducts(sortId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doFinally { progressBarLiveData.value = false }
                .subscribe(object : NikeSingleObserver<List<Product>>(compositeDisposable) {
                    override fun onSuccess(t: List<Product>) {
                        _productLiveData.value = t
                    }
                })
            return productLiveData
        } else throw IllegalArgumentException("sortId must be 'SORT' Field in Product DataClass..!")
    }

اینهم دوتا ریکوئستی که از ویو گرفتم: (من یه متدی نوشتم برای اینکه شاید یکم خلوت تر بشه موقع initialize کردن ریسایکلر ویو ها که این زیر میزارمش..)

 mainViewModel.requestProductLists(SORT_LATEST).observe(viewLifecycleOwner,{
            initializeRecyclerViews(
                requireContext(),
                latestProductRv,
                RecyclerView.HORIZONTAL,
                it,
                productListAdapter
            )
        })
        mainViewModel.requestProductLists(SORT_POPULAR).observe(viewLifecycleOwner,{
            initializeRecyclerViews(
                requireContext(),
                popularProductRv,
                RecyclerView.HORIZONTAL,
                it,
                productListAdapter
            )
        })

فانکشن ریسایکر ویو (اضافه):

fun initializeRecyclerViews(
        context: Context,
        recyclerView: RecyclerView,
        orientation: Int,
        products: List<Product>,
        adapter: ProductListAdapter
    ) {
        recyclerView.layoutManager =
            LinearLayoutManager(context, orientation, false)
        adapter.products = products as ArrayList<Product>
        recyclerView.adapter = adapter

    }

مشکلی که بود نمیدونستم دقیقا چی سرچ کنم تا بتونم به جوابم برسم.. امیدوارم بتونم اینجا جوابمو بگیرم..:)

فایل پیوست

0
حذف شده

چنین کاری فکر می کنم اشتباه چون فلسفه ی لایو دیتا اینکه که شما یک لایو دیتا بسازی و بیایید بهش گوش کنید تا زمانی که از بین بره اون اون آبجکت. حالا شما میایید و می گید دوباره بیا و از همین آبجکت برای من به یک چیز دیگه گوش بده و در نتیجه اون یکی هم دیتا هاش میشه مثل این میشه یک راه حل برای این کار به نظر میاد اینه که بیایید و مجدد یک آبجکت از ویو مدل بسازید و اگر هم بشه ساخت به خیلی سنگین می کنه و احتمال مشکل مموری وجود داره در واقع تو دنیای نرم افزار ما بین چیزای مختلف trade off می کنیم یعنی الان توی این مسعله اینکه یک آبجکت بسازید مشکل خاصی نیست و اینکه بخواید به جای ساخت یک ویو مدل برای اینکه کد کمتری بنویسید و یک آبجکت از ویو مدل بسازید اینجا ترید آف جالبی نیست به نظرم

 

فایل پیوست

MohammadMoghadasi

توسط

MohammadMoghadasi

5 بهمن 99

حذف شده
بله این رو میدونیم، توی جوابها هم بهش اشاره کردم..من تصمیم گرفتم خود متد ریپازیتوری رو توسط ویو مدل ریترن کنم توی ویو و اونجا Observe کنم...
1
حذف شده

یه جواب کوتاهی خودم بدم ولی میخوام که اگه راه دیگه ای وجود داره از این روش استفاده نکنم.. اونم این هستش که متد ریپازیتوری رو با استفاده از یه متد ViewModel پاس بدید به ویو و اونجا روش Observe بشه.. ولی اینطوری باعث شلوغ شدن کدهای ویو میشه و به نظرم بهتره هر کثیف کاری میخوایم بکنیم توی ViewModel باشه..

 

برای مثال:

 

MainViewModel:

fun requestProduct(sortId: Int): Single<List<Product>> {
        return productRepository.getProducts(sortId).doFinally { progressBarLiveData.value = false }
    }

MainFragment:

 mainViewModel.requestProduct(SORT_POPULAR).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : NikeSingleObserver<List<Product>>(mainViewModel.compositeDisposable) {
                override fun onSuccess(t: List<Product>) {
                    initializeRecyclerViews(
                        requireContext(),
                        popularProductRv,
                        RecyclerView.HORIZONTAL,
                        t,
                        productListAdapter
                    )
                }

            })

ولی همونطوری که میبینین ما باید copositeDisposable رو داخل View به متد بدیم که به نظرم اشتباه باشه از نظر معماری..

و دلیل اصلی که میشه از این استفاده نکرد اینکه state دیتا رو نگه نمیداره.. و در صورت رفرش اکتیویتی یا فرگمنت ما دوباره باید ریکوئست بزنیم..

فایل پیوست

ابوالفضل رضایی

توسط

ابوالفضل رضایی

12 دی 99

حذف شده
سلام ابوالفضل، درستش همینه باید هر بار تازه سازی میکنی داده ها دوباره دریافت بشن اما حتی اگر بخوای داده ها رو نگهداری باید Room استفاده بشه که هنوز استاد تا اینجا در این پروژه سراغ ذخیره سازی داده رو گوشی نرفته ولی متوجه نشدم منظورت اشتباه ازنظر معماری چیه، چیزی دوباره نویسی شده ؟
مهرداد

13 دی 99

0
حذف شده

سلام ابوالفضل جان 

امیدوارم عالی باشین

 

من هنوز به جلسه نرسیدم و نسبت به چالش اطلاعی ندارم

تا فردا/پسفردا خودم رو به جلسه میرسونم و در همین تاپیک شما رو راهنمایی میکنم.

اما از اونجایی که چالش هست حتما حتما حسابی خودتون زمان بذارید و روش فکر کنید(از انجایی که سر فصل آخر هست) و به راه حل هاتون فکر کنید و پیاده سازی کنید و اینجا به اشتراک بذارید تا با هم در رابطه با مزایا و معایب راه حل های احتمالی گفتگو کنیم.

 

فایل پیوست

پوریا شفیعی

توسط

پوریا شفیعی

12 دی 99

0
حذف شده

مهرداد جان چون که کامنت ها لیمیت داره اینجا برات جوابتو گذاشتم: 

ببین به قول استاد توی معماری سخت گیری دست developer عه.. من ترجیح میدم متد هارو توی ویو Observe نکنم و فقط از لایو دیتا تا حد ممکن استفاده کنم، به علاوه اینکه  کامپوزیت دیسپوزیبل رو نباید توی View به متدمون بدیم به نظرم، از تمیزی کار کم میکنه..
چیز دیگه ای که هست اگه بخوای توی Room ذخیره کنی خیلی خیلی طول میکشه کاربر ویو براش اماده بشه، خودت فرض کن، اول سمت سرور ریکوئست بره، بعد تا میاد بیاد یکم زمان طول میکشه، بعد الان درخواست بدیم توی دیتابیس ذخیره بشه، بعد از دیتابیس فراخونی کنیم.. یه عملیات فاجعه ای میشه توی پرفورمنس به نظرم

فایل پیوست

ابوالفضل رضایی

توسط

ابوالفضل رضایی

13 دی 99

حذف شده
قسمت اول سوال که حرفی ندارم اما قسمت دوم خب تنها راه برای درخواست نفرستادن مجدد دیگه همینه یا باید داده ها رو cach کنی یا تو دیتابیس ذخیره کنی یا sharedprre خلاصه باید یه جوری داده رو گوشی داشته باشی که نیاز به درخواست مجدد نباشه یه جستجو در مورد caching انجام بده غیر اینا چیزه دیگه ای اگر باشه نمی دونم
مهرداد

13 دی 99

0
حذف شده

.

فایل پیوست

ابوالفضل رضایی

توسط

ابوالفضل رضایی

14 دی 99

0
حذف شده

سلام وقت بخیر

منظورتون از تک به تک انجام بده کار رو؟ چیه دقیقا؟

ممنون

فایل پیوست

MohammadMoghadasi

توسط

MohammadMoghadasi

4 بهمن 99

حذف شده
ببینین موقعی که من این متد رو کال میکنم لایو دیتا آخرین استیت رو به من میده، آخرین ریکوئست رو، و من میخواستم که تک به تک ریکوئست ها بیان و اجرا بشن و بعد بره بعدی.. که باید از روش دیگه ای که گفتم توی پاسخای دیگش بریم
حذف شده
یعنی میخوای که یک بار صدا بزنی متد رو بعد برای همه ۴ تا حالتی که استاد گفت اجرا بشه ؟
MohammadMoghadasi

4 بهمن 99

حذف شده
بله
1
حذف شده

درود به همه دوستان

من به این شکل عمل کردم کار میکنه و مشکلی هم نداره

class MainFragment : NikeFragment() {
 val mainViewModel:MainViewModel by viewModel()
    val productListAdapter:ProductListAdapter by inject()
    val productListAdapter2:ProductListAdapter by inject()
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {latestProductsRv.layoutManager =
            LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
        latestProductsRv.adapter = productListAdapter
        super.onViewCreated(view, savedInstanceState)
        mainViewModel.productsLiveData.observe(viewLifecycleOwner){
            Timber.i(it.toString())
            productListAdapter.products = it as ArrayList<Product>

        }
        popularProductsRv.layoutManager =
                LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
        popularProductsRv.adapter = productListAdapter2
        super.onViewCreated(view, savedInstanceState)
        mainViewModel.productsLiveData2.observe(viewLifecycleOwner){
            Timber.i(it.toString())
            productListAdapter2.products = it as ArrayList<Product>

        }

 

class MainViewModel(productRepository: ProductRepository, bannerRepository: BannerRepository) : NikeViewModel() {
    val productsLiveData=MutableLiveData<List<Product>>()
    val productsLiveData2=MutableLiveData<List<Product>>()
    val bannersLiveData = MutableLiveData<List<Banner>>()
    init {
        progressBarLiveData.value=true

        productRepository.getProducts(SORT_LATEST)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
            .doFinally { progressBarLiveData.value=false }
                .subscribe(object :NikeSingleObserver<List<Product>>(compositeDisposable){
                    override fun onSuccess(t: List<Product>) {
                        productsLiveData.value = t
                    }
                })
        productRepository.getProducts(SORT_POPULAR)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doFinally { progressBarLiveData.value=false }
                .subscribe(object :NikeSingleObserver<List<Product>>(compositeDisposable){
                    override fun onSuccess(t: List<Product>) {
                        productsLiveData2.value = t
                    }
                })
        bannerRepository.getBanners()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : NikeSingleObserver<List<Banner>>(compositeDisposable) {
                override fun onSuccess(t: List<Banner>) {
                    bannersLiveData.value = t
                }
            })
    }
}

شما هم میتونید تست کنید ببینید جواب میده؟ و اشکالش رو اینجا به اشتراک بزارید

فایل پیوست

ali asadollahi

توسط

ali asadollahi

21 اسفند 99

حذف شده
سلام. شما از Adapter جداگانه برای هر Sort استفاده کردی درسته؟ میخوام بدونم این روش آیا اصولی هست یا روش بهتر دیگه های هم هست؟ ممنون.
رضا فرجی

10 فروردین 00