20 β Loading va progress holatlari¶
β¬ οΈ Oldingi: 19 β URL va query string Β· π Kitob boshi Β· Keyingi: 21 β Lazy, polling, navigatsiya β‘οΈ
Bu bobda: har bir Livewire so'rovi serverga borib-keladi β bu vaqt oladi. Shu vaqt davomida ekranda hech nima o'zgarmasa, foydalanuvchi ilova "qotib qoldi" deb o'ylaydi va tugmani qayta-qayta bosadi. Bu bobda biz ana shu "kutish lahzasini" ko'rinadigan qilamiz:
wire:loadingbilan spinner va matn ko'rsatamiz,wire:targetbilan har bir amalga o'z indikatorini beramiz,wire:loading.attrbilan ikki marta bosishni butunlay to'xtatamiz,wire:dirtybilan saqlanmagan o'zgarishni belgilaymiz,wire:offlinebilan internet yo'qolganini bildiramiz β va oxirida skeleton ekran bilan kutishni chiroyli qilamiz.
Muammo: server javobi vaqt oladi¶
7-bobda ko'rganimizdek, wire:click="save" bosilganda Livewire serverga so'rov yuboradi, server javobni qaytaradi, keyin ekran yangilanadi. Bu jarayon ko'pincha tez β bir necha o'ndan soniya. Lekin har doim ham emas: server bandligi, sekin internet, og'ir hisob-kitob yoki katta fayl β bularning hammasi javobni sekinlashtiradi. Foydalanuvchi tugmani bosadi, lekin ekranda hech narsa o'zgarmaydi.
Foydalanuvchi nima o'ylaydi? "Bosildimi yo'qmi? Balki tegmadim?" β va yana bosadi. Yana. Va yana. Natijada bir marta bo'lishi kerak bo'lgan amal (masalan, "Buyurtma berish") uch marta bajariladi: uchta bir xil buyurtma, uchta SMS, uchta to'lov. Bu jiddiy xato β texnik tilda buni takroriy yuborish (double submission) deyiladi.
Hayotiy o'xshatish β lift tugmasi. Liftni chaqirish uchun tugmani bosasiz. Yaxshi liftda tugma darhol yonadi β siz "qabul qilindi, lift kelyapti" degan signalni ko'rasiz va xotirjam kutasiz. Endi tasavvur qiling, tugma yonmaydi. Bosdingiz β hech nima. Yana bosasiz, yana hech nima. Lift kelyaptimi yo'qmi β bilmaysiz. Asabiylashib tugmani urib-urib turasiz. Mana shu β yonmagan lift tugmasi β sizning loading indikatori yo'q ilovangiz. Foydalanuvchiga "qabul qildim, ishlayapman" degan signalni darhol berish kerak.
Texnik ta'rif bilan: loading holati (loading state) β bu so'rov serverga ketib, javob qaytguncha bo'lgan oraliqda foydalanuvchiga "kutilmoqda" signalini ko'rsatish. Livewire buni hech qanday JavaScript yozmasdan, faqat HTML atributlari bilan hal qiladi. Eng asosiysi β wire:loading.
wire:loading β kutish davomida ko'rinadi¶
wire:loading atributi qo'yilgan element oddiy holatda yashirin turadi va faqat Livewire so'rovi davom etayotgan paytda ko'rinadi. So'rov tugashi bilan u yana yashirinadi. Hech qanday kod, hech qanday holat (property) kerak emas β atributning o'zi yetadi:
{{-- resources/views/components/β‘loading-test.blade.php --}}
<div>
<button wire:click="save">Saqlash</button>
<span wire:loading>Yuklanmoqda...</span>
</div>
Bu yerda nima sodir bo'ladi:
- Boshida
<span>ko'rinmaydi (Livewire ungadisplay: noneqo'yadi). - Foydalanuvchi "Saqlash" tugmasini bosadi β so'rov serverga ketadi.
- So'rov davom etayotganida
<span>paydo bo'ladi: "Yuklanmoqda...". - Server javob qaytaradi β
<span>yana yashirinadi.
Bu shunchalik sodda. Mana shu bitta qator butun sahifaga "men ishlayapman" degan signalni qo'shadi.
Eslatma β har qanday so'rovda yonadi.
wire:targetbelgilanmasa,wire:loadingshu komponentdagi istalgan so'rov davomida ko'rinadi: tugma bosilishi ham,wire:model.liveo'zgarishi ham, validatsiya ham. Tez oradawire:targetbilan buni aniqlashtiramiz.
Spinner uchun ham
wire:loading matn bilan cheklanmaydi. Ichiga aylanuvchi spinner ikonkasini, progress chizig'ini yoki istalgan HTML qo'yishingiz mumkin:
<div wire:loading>
<svg class="animate-spin" ...><!-- aylanuvchi doira --></svg>
<span>Yuborilmoqda...</span>
</div>
animate-spin β Tailwind klassi bo'lib, elementni aylantiradi. Tailwindsiz ham oddiy CSS animatsiya bilan qilsa bo'ladi.
wire:loading.remove β teskari mantiq¶
Ba'zan teskari kerak bo'ladi: element odatda ko'rinadi, lekin so'rov davomida yashirinishi kerak. Buning uchun .remove modifikatorini qo'shamiz:
<div>
{{-- odatda ko'rinadi, so'rov paytida YASHIRINADI --}}
<span wire:loading.remove>Saqlashga tayyor</span>
{{-- odatda yashirin, so'rov paytida KO'RINADI --}}
<span wire:loading>Saqlanmoqda...</span>
</div>
Bu ikkovi birgalikda juda foydali naqshni beradi β almashinuvchi matn. So'rov yo'q paytida "Saqlashga tayyor", so'rov davomida "Saqlanmoqda..." ko'rinadi. Foydalanuvchi har lahzada ilova qaysi holatda ekanini biladi.
O'ylab ko'ring.
wire:loading"kutish paytida ko'rsat",wire:loading.removeesa "kutish paytida yashir". Ikkalasini bir element ustida bir vaqtda qo'ymang β bu mantiqsiz. Lekin ikkita alohida elementga qo'yib, biri ikkinchisining o'rnini egallashini ta'minlash β eng keng tarqalgan UI naqshi.
wire:target β qaysi amalni kutyapmiz?¶
Endi muhim muammoga keldik. Tasavvur qiling, sahifada ikkita tugma bor: "Saqlash" va "O'chirish". Har biriga oddiy wire:loading qo'ysangiz, istalgan biri bosilganda ikkalasining ham indikatori yonadi. Chunki Livewire uchun ular bir komponentdagi "so'rov", farqi yo'q.
Lekin foydalanuvchi "Saqlash"ni bosgan bo'lsa, "O'chirilmoqda..." degan yozuvni ko'rishi mantiqsiz. Bu yerda wire:target yordamga keladi: u indikatorni faqat muayyan amalga bog'laydi.
<div>
<button wire:click="save">Saqlash</button>
<button wire:click="delete">O'chirish</button>
{{-- faqat save() ishlayotganida ko'rinadi --}}
<span wire:loading wire:target="save">Saqlanmoqda...</span>
{{-- faqat delete() ishlayotganida ko'rinadi --}}
<span wire:loading wire:target="delete">O'chirilmoqda...</span>
</div>
Endi har bir indikator faqat o'z amaliga javob beradi. "Saqlash"ni bossangiz β faqat "Saqlanmoqda..." chiqadi, "O'chirilmoqda..." jim turadi. Aynan kerakli xulq.
Bir nechta amalni nishonga olish¶
Ba'zan bitta indikator bir nechta amalga javob berishi kerak. Masalan, "tarmoq band" degan umumiy belgi ham saqlashda, ham o'chirishda chiqsin. Amal nomlarini vergul bilan sanang:
Parametrli amalni nishonga olish¶
7-bobda parametr bilan amal chaqirishni ko'rgan edik: wire:click="delete({{ $post->id }})". Bunday amalni nishonga olishda parametrni ham aniqlashtirsangiz bo'ladi β masalan, ro'yxatdagi har bir element o'z spinneriga ega bo'lsin:
@foreach ($posts as $post)
<div wire:key="post-{{ $post->id }}">
{{ $post->title }}
<button wire:click="delete({{ $post->id }})">O'chirish</button>
{{-- faqat AYNAN shu post o'chirilayotganda spinner --}}
<span wire:loading wire:target="delete({{ $post->id }})">β³</span>
</div>
@endforeach
Endi ro'yxatda 5-postni o'chirsangiz, faqat 5-postning yonida spinner chiqadi, qolgan 4 tasi tinch turadi. Bu β uzun ro'yxatlarda juda silliq tajriba.
Nega
wire:targetmuhim?wire:loadingning kuchiwire:targetda. Usiz indikator "bir narsa yuklanmoqda" deydi β ammo nimaligi noma'lum.wire:targetbilan u aniq "shu amal bajarilmoqda" deydi. Ko'p tugmali, ko'p elementli sahifalarda bu farq tartibsizlik bilan professional tajriba o'rtasidagi chegaradir.
wire:model'ni ham nishonga olish mumkin
wire:target faqat amallar uchun emas. wire:model.live bilan bog'langan maydonni ham nishonga olsa bo'ladi β bu qidiruv maydonida juda asqotadi:
<input wire:model.live.debounce.400ms="query">
<span wire:loading wire:target="query">Qidirilmoqda...</span>
query β bu amal emas, balki property nomi. Foydalanuvchi yozayotganda spinner chiqadi.
wire:loading.attr="disabled" β ikki marta bosishni to'xtatish¶
Indikator ko'rsatish yaxshi, lekin u takroriy bosishni o'zi to'xtatmaydi. Foydalanuvchi "Saqlanmoqda..." yozuvini ko'rib turib ham tugmani yana bosishi mumkin. Buni butunlay oldini olish uchun tugmani so'rov davomida o'chirib qo'yamiz (disabled qilamiz). Buning uchun wire:loading.attr ishlatiladi β u so'rov davomida elementga atribut qo'shadi:
Endi "Saqlash" bosilishi bilan tugma bosilmaydigan holatga o'tadi (disabled atributi qo'shiladi), so'rov tugagach yana faollashadi. Foydalanuvchi qancha bossa ham β ikkinchi so'rov ketmaydi. Bu takroriy yuborishdan himoyaning eng ishonchli usuli.
Hayotiy o'xshatish β bankomat. Pul yechayotganingizda bankomat tugmalarini bloklaydi β "Iltimos, kuting" deb yozadi va siz boshqa tugma bosa olmaysiz. Agar bloklamasa, sabrsiz odam tugmalarni bosib, ikki marta pul yechib yuborardi.
wire:loading.attr="disabled"β sizning ilovangizning ana shu bloki.
Faqat disabled emas β wire:targetni ham qo'shing
wire:loading.attr="disabled"ni yolg'iz qo'ysangiz, tugma shu komponentdagi har qanday so'rovda o'chadi β hatto yonidagi qidiruv maydoniga yozganingizda ham. Bu chalkash. Doim wire:target bilan birga ishlating, shunda tugma faqat o'z amalida bloklanadi:
wire:loading.class β uslubni o'zgartirish¶
Atribut qo'shish o'rniga so'rov davomida elementga CSS klass qo'shsangiz ham bo'ladi. Bu vizual fikr-bildirish (matni "xira"lashtirish, tugmani kulrang qilish va h.k.) uchun ideal:
{{-- so'rov davomida tugma yarim shaffof bo'ladi --}}
<button wire:click="save"
wire:loading.class="opacity-50"
wire:target="save">
Saqlash
</button>
opacity-50 β Tailwind klassi bo'lib, elementni 50% shaffof qiladi. So'rov tugashi bilan klass olib tashlanadi va tugma yana to'liq ko'rinadi. Bir nechta klass qo'shsa bo'ladi: wire:loading.class="opacity-50 cursor-wait".
Teskari variant ham bor β .class.remove so'rov davomida klassni olib tashlaydi:
{{-- odatda "active" klassi bor, so'rov paytida olib tashlanadi --}}
<div class="card active"
wire:loading.class.remove="active"
wire:target="refresh">
...
</div>
Uchta vositani solishtiring
wire:loading/.removeβ elementni ko'rsatadi/yashiradi (matn, spinner).wire:loading.attrβ elementga atribut qo'shadi (disabled,readonly).wire:loading.class/.class.removeβ elementga CSS klass qo'shadi/oladi (vizual uslub).
Uchalasini ham wire:target bilan birga ishlating. Ko'pincha bir tugmaga bir nechtasini birga qo'yamiz (pastdagi amaliy misolga qarang).
wire:dirty β saqlanmagan o'zgarish bor¶
Hozirgacha biz so'rov davomidagi holatni ko'rdik. Lekin yana bir foydali holat bor: foydalanuvchi maydonni o'zgartirdi, lekin hali saqlamadi. Buni texnik tilda "kir" (dirty) holat deyiladi β ya'ni ekrandagi qiymat serverdagi qiymatdan farq qiladi.
wire:dirty atributi qo'yilgan element faqat shu farq mavjud paytda ko'rinadi:
<div>
<input type="text" wire:model="title">
{{-- faqat o'zgarish saqlanmagan paytda ko'rinadi --}}
<span wire:dirty>β Saqlanmagan o'zgarishlar bor</span>
<button wire:click="save">Saqlash</button>
</div>
Foydalanuvchi maydonga yozishni boshlashi bilan "β Saqlanmagan o'zgarishlar bor" belgisi paydo bo'ladi. "Saqlash" bosib, server qiymatni qabul qilgach β belgi yo'qoladi. Bu foydalanuvchini "ishingni saqlashni unutma" deb ogohlantiradi.
wire:dirty ham wire:dirty.class ko'rinishida CSS klass qo'sha oladi β masalan, o'zgartirilgan maydon chetini sariq qilish:
{{-- o'zgartirilganda maydon chetiga sariq ramka qo'shiladi --}}
<input type="text"
wire:model="title"
wire:dirty.class="border-yellow-500">
Eslab qoling.
wire:dirtyso'rov bilan emas, qiymat farqi bilan ishlaydi. So'rov ketmagan bo'lsa ham, foydalanuvchi maydonni o'zgartirgan zahoti yonadi va saqlangach o'chadi. Bu uniwire:loadingdan ajratib turadi.
Livewire 3 da qanday edi?
wire:dirty Livewire 3 da ham bor edi va asosan xuddi shunday ishlardi. Livewire 4 da wire:modelning standart xulqi deferred bo'lib qolgani uchun (.live qo'shmasangiz, qiymat keyingi amalda yuboriladi β 6-bobga qarang), wire:dirty bu deferred oraliqda β ya'ni "yozdim, lekin hali serverga ketmadi" lahzasida β ayniqsa qadrli bo'ldi.
wire:offline β internet yo'qolganda¶
Foydalanuvchining interneti uzilib qolsa, hech qanday Livewire so'rovi ishlamaydi β tugma bosiladi, lekin javob kelmaydi. Foydalanuvchi nima bo'layotganini bilmaydi. wire:offline aynan shu holat uchun: u faqat brauzer oflayn (internetsiz) bo'lganda ko'rinadi:
<div wire:offline
style="background:#dc2626; color:#fff; padding:8px; text-align:center;">
β οΈ Internet aloqasi yo'q. Ulanish tiklanmaguncha o'zgarishlar saqlanmaydi.
</div>
Brauzer internetni yo'qotishi bilan bu ogohlantirish chiqadi, ulanish tiklanishi bilan o'zi yo'qoladi. wire:offline.class va wire:offline.attr ham bor β masalan, oflaynda barcha tugmalarni o'chirib qo'yish:
Maslahat.
wire:offlineni odatda bitta joyga β sahifa tepasiga global tasma sifatida qo'yish kifoya. Har bir elementga alohida qo'yish shart emas; bitta ko'zga tashlanadigan ogohlantirish foydalanuvchiga yetarli signal beradi.
Skeleton ekran va spinner β UX'ni yaxshilash¶
Endi loading tajribasini chiroyli qilish haqida. Ikki keng tarqalgan naqsh bor:
1. Spinner β kichik aylanuvchi indikator. Qisqa kutishlar (tugma bosish, saqlash) uchun ideal. Yuqorida ko'rganimizdek, wire:loading ichiga aylanuvchi ikonka qo'yamiz.
2. Skeleton ekran (skeleton screen) β bu kontent yuklanguncha uning kulrang "soyasi"ni ko'rsatish. Tasavvur qiling, post ro'yxati yuklanmoqda: bo'sh ekran o'rniga siz kulrang to'rtburchaklar ko'rasiz β go'yo postlar joyida turibdi, faqat hali rangsiz. Kontent kelishi bilan soyalar haqiqiy matnga almashadi.
Hayotiy o'xshatish β restoran stoli. Mehmonni kutayotgan restoran stolini tasavvur qiling: likopcha, vilka, qoshiq oldindan terib qo'yiladi β taom hali kelmagan bo'lsa ham. Mehmon "meni kutishyapti, hammasi tayyor" deb his qiladi. Skeleton ekran ham shunday: kontent kelmasdan oldin uning "joyini" tayyorlab qo'yadi. Bo'sh ekran esa β yalang'och stol kabi β "bu yer tashlandiq" degan taassurot qoldiradi.
Skeletonni odatda wire:loading bilan amal davomida ko'rsatamiz:
<div>
{{-- yuklash davomida SKELETON soya --}}
<div wire:loading wire:target="loadPosts">
<div class="skeleton-line"></div>
<div class="skeleton-line"></div>
<div class="skeleton-line"></div>
</div>
{{-- yuklash tugagach HAQIQIY kontent --}}
<div wire:loading.remove wire:target="loadPosts">
@foreach ($posts as $post)
<p wire:key="p-{{ $post->id }}">{{ $post->title }}</p>
@endforeach
</div>
</div>
.skeleton-line β bu shunchaki kulrang fonli, biroz yumaloq burchakli to'rtburchak (oddiy CSS). Eng yaxshi skeletonlar yengil "miltillash" (shimmer) animatsiyasiga ega bo'ladi, lekin oddiy kulrang ham bo'sh ekrandan ancha yaxshi.
Skeleton qachon kerak?
Skeleton ekran dastlabki yuklash (sahifa yoki katta blok birinchi marta to'layotganida) uchun eng yaxshi. Kichik amallar (bir tugma bosish) uchun esa spinner yetarli. Skeleton ko'pincha lazy komponentlar bilan birga ishlatiladi β bu haqda keyingi, 21-bobda (placeholder() metodi) batafsil gaplashamiz.
Amaliy 1: to'liq submit tugmasi¶
Endi o'rgangan vositalarni birlashtirib, professional submit tugmasini yasaymiz. Yaxshi submit tugmasi bir vaqtning o'zida bir nechta ishni qiladi:
- so'rov davomida matnini "Saqlash" dan "Saqlanmoqda..." ga o'zgartiradi (
wire:loading+.remove); - ikki marta bosishni to'xtatadi (
wire:loading.attr="disabled"); - vizual jihatdan "band" ko'rinadi (
wire:loading.class).
Quyidagi misol β jonli Livewire v4.3.1 loyihada ishlab tekshirilgan komponentdan olingan:
{{-- resources/views/components/β‘loading-test.blade.php --}}
<?php
use Livewire\Component;
new class extends Component
{
public function save(): void
{
usleep(200000); // 0.2s β sekin serverni taqlid qilamiz
// (haqiqiy loyihada bu yerda Post::create([...]) bo'lardi)
}
};
?>
<div>
<button wire:click="save"
wire:loading.attr="disabled"
wire:target="save">
{{-- so'rov YO'Q paytida ko'rinadi --}}
<span wire:loading.remove wire:target="save">Saqlash</span>
{{-- so'rov DAVOMIDA ko'rinadi --}}
<span wire:loading wire:target="save">Saqlanmoqda...</span>
</button>
</div>
Diqqat qiling: tugma ichida ikkita <span> bor. Biri "Saqlash" (wire:loading.remove bilan β so'rov paytida yashirinadi), ikkinchisi "Saqlanmoqda..." (wire:loading bilan β so'rov paytida ko'rinadi). Ikkalasi ham bir xil wire:target="save" ga bog'langan. Natijada tugma matni so'rov boshlanganda "Saqlash" dan "Saqlanmoqda..." ga, tugaganda esa orqaga almashadi β va shu paytda tugmaning o'zi bosilmaydi.
Nega tugma ichida
wire:targetham kerak? Tugmaning o'zidawire:click="save"bor, demak u nishonni "biladi". Lekin ichidagi<span>lar nishonni bilmaydi β shuning uchun ularga hamwire:target="save"qo'yamiz. Aks holda ular komponentdagi har qanday so'rovga reaksiya berib qolardi.
Amaliy 2: qidiruvda spinner¶
Ikkinchi keng tarqalgan holat β jonli qidiruv (14-bobga ishora). Foydalanuvchi yozayotganida natijalar serverdan kelguncha biroz vaqt o'tadi. Shu oraliqda spinner ko'rsatish β foydalanuvchiga "qidiryapman, kuting" deb aytadi. Bu ham yuqoridagi jonli komponentdan:
{{-- resources/views/components/β‘loading-test.blade.php --}}
<?php
use Livewire\Component;
new class extends Component
{
public string $query = '';
public array $results = [];
public function search(): void
{
usleep(300000); // 0.3s β sekin qidiruvni taqlid qilamiz
$this->results = $this->query === ''
? []
: ["Natija: {$this->query} (1)", "Natija: {$this->query} (2)"];
}
};
?>
<div>
<input type="text"
wire:model.live.debounce.400ms="query"
placeholder="Qidirish...">
{{-- faqat "query" yangilanayotganida ko'rinadi --}}
<span wire:loading wire:target="query">Qidirilmoqda...</span>
<ul>
@foreach ($results as $i => $r)
<li wire:key="r-{{ $i }}">{{ $r }}</li>
@endforeach
</ul>
</div>
E'tibor bering: wire:target="query" β bu yerda query amal emas, balki property nomi. Foydalanuvchi yozganda wire:model.live serverga so'rov yuboradi, va shu so'rov davomida "Qidirilmoqda..." chiqadi. .debounce.400ms esa har bosishda emas, yozish to'xtaganidan 0.4 soniya keyin so'rov yuboradi β bu keraksiz so'rovlarni kamaytiradi (6-bobga qarang).
Tasdiqlangan. Yuqoridagi ikkala misol (submit tugmasi va qidiruv spinneri) bir xil
β‘loading-test.blade.phpkomponentida birga turibdi va jonli Livewire v4.3.1 loyihada HTTP 200 bilan render bo'ldi: spinner so'rov davomida ko'rindi, submit tugmasi bloklandi.
To'liq misol: CRUD ilovasida barcha loading holatlari¶
16-bobda qurgan CRUD ilovasini eslang β postlarni yaratish, tahrirlash, o'chirish. Endi unga shu bobda o'rgangan barcha loading holatlarini qo'shamiz, shunda har bir amalda foydalanuvchi nima bo'layotganini aniq ko'radi:
{{-- CRUD ilovasiga loading holatlarini qo'shish (qism) --}}
<div>
{{-- 1) Oflayn ogohlantirish β sahifa tepasida bitta marta --}}
<div wire:offline class="offline-banner">
β οΈ Internet yo'q β o'zgarishlar saqlanmaydi.
</div>
{{-- 2) Forma: submit tugmasi + dirty belgi --}}
<form wire:submit="save">
<input type="text" wire:model="title"
wire:dirty.class="border-yellow-500">
{{-- saqlanmagan o'zgarish belgisi --}}
<span wire:dirty wire:target="title">β Saqlanmagan</span>
{{-- band va matn almashinuvchi submit tugmasi --}}
<button type="submit"
wire:loading.attr="disabled"
wire:target="save">
<span wire:loading.remove wire:target="save">Saqlash</span>
<span wire:loading wire:target="save">Saqlanmoqda...</span>
</button>
</form>
{{-- 3) Postlar ro'yxati: har postda o'z o'chirish spinneri --}}
<ul>
@foreach ($posts as $post)
<li wire:key="post-{{ $post->id }}">
{{ $post->title }}
<button wire:click="delete({{ $post->id }})"
wire:loading.attr="disabled"
wire:target="delete({{ $post->id }})">
O'chirish
</button>
{{-- faqat AYNAN shu post o'chirilayotganda --}}
<span wire:loading wire:target="delete({{ $post->id }})">β³</span>
</li>
@endforeach
</ul>
</div>
Bu bitta blokda biz qo'shganlarimiz:
- Oflayn tasma β internet uzilsa, sahifa tepasida qizil ogohlantirish (
wire:offline). - Dirty belgi β maydon o'zgartirilganda "β Saqlanmagan" yonadi va maydon cheti sariqlashadi (
wire:dirty,wire:dirty.class). - Aqlli submit tugmasi β so'rov davomida matni "Saqlanmoqda..." ga o'zgaradi va bloklanadi (
wire:loading+.attr+wire:target). - Har postda alohida spinner β parametrli
wire:target="delete({{ $post->id }})"tufayli faqat o'chirilayotgan post yonida β³ chiqadi.
Mana shunday β bir nechta sodda atribut bilan ilovangiz "tirik" va ishonchli his etiladi. Foydalanuvchi har lahzada nima bo'layotganini biladi, hech qachon "qotib qoldimi?" deb o'ylamaydi va hech qachon tasodifan ikki marta bosib yubormaydi.
Xulosa¶
- Loading holati β kutish lahzasini ko'rinadigan qilish. Server javobi vaqt oladi; signal bo'lmasa, foydalanuvchi ilova qotgan deb o'ylab tugmani qayta bosadi (takroriy yuborish). "Yonmagan lift tugmasi" muammosi.
wire:loadingβ element odatda yashirin, so'rov davomida ko'rinadi.wire:loading.removeβ teskari: odatda ko'rinadi, so'rov davomida yashirinadi. Ikkovi birga "almashinuvchi matn" beradi.wire:target="save"β indikatorni faqat muayyan amalga bog'laydi.wire:targetsizwire:loading"bir narsa" yuklanmoqda deydi; u bilan aniq amalni ko'rsatadi. Ko'p tugmali sahifalarda shart.wire:target="save, delete"β bir nechta amal;wire:target="delete({{ $id }})"β parametr bilan (ro'yxatda har element o'z spinneriga ega).wire:modelproperty nomini ham nishonga olsa bo'ladi.wire:loading.attr="disabled"β so'rov davomida tugmani bloklaydi β ikki marta bosishni butunlay to'xtatadi. Doimwire:targetbilan birga.wire:loading.class="..."/.class.removeβ so'rov davomida CSS klass qo'shadi/oladi (vizual "band" ko'rinishi).wire:dirtyβ saqlanmagan o'zgarish belgisi (so'rov emas, qiymat farqi bilan ishlaydi).wire:offlineβ internet yo'qolganida ogohlantirish.- Skeleton ekran β kontent kelmasdan oldin uning kulrang "soyasi"ni ko'rsatish ("tayyorlangan restoran stoli"). Dastlabki yuklash uchun spinnerdan yaxshiroq; ko'pincha lazy komponentlar bilan (21-bob).
- Professional submit tugmasi =
wire:loading.remove/wire:loading(matn almashinuvi) +wire:loading.attr="disabled"(blok) +wire:target(aniqlik), hammasi birga.
Amaliy mashqlar¶
-
Almashinuvchi tugma (oson). Bitta
wire:click="save"tugmasini yarating. Ichiga ikkita<span>qo'ying: biriwire:loading.removebilan "Yuborish", ikkinchisiwire:loadingbilan "Yuborilmoqda...".save()metodi ichigausleep(1000000);(1 soniya) qo'yib, so'rovni sekinlashtiring va matn almashishini ko'zingiz bilan ko'ring. Yo'naltirish: ikkala<span>ga hamwire:target="save"qo'shing. -
Ikki tugma, ikki indikator (osonβo'rta). Sahifaga "Saqlash" (
save) va "O'chirish" (delete) tugmalarini qo'ying. Har biriga alohida indikator yozing:wire:loading wire:target="save"β "Saqlanmoqda...",wire:loading wire:target="delete"β "O'chirilmoqda...". Bir tugmani bosganda faqat o'sha indikator chiqishini tekshiring. Yo'naltirish:wire:targetbo'lmasa nima bo'lishini ham sinab ko'ring β ikkalasi ham yonadi. -
Takroriy yuborishni to'xtatish (o'rta). Forma yarating,
save()ichigausleep(2000000);(2 soniya) qo'ying. Avvalwire:loading.attr="disabled"siz tugmani bir necha marta tez-tez bosib,save()necha marta ishlaganini (masalan, hisoblagich property bilan) kuzating. Keyinwire:loading.attr="disabled" wire:target="save"qo'shib, qayta sinang β endi nechta? Yo'naltirish:disabledqo'shilgach, qancha bossangiz ham bitta so'rov ketadi. -
Dirty va offline (o'rta). Matn maydoni va "Saqlash" tugmasi bo'lgan forma yarating.
wire:dirtybelgisi qo'shing β maydon o'zgartirilganda "Saqlanmagan o'zgarishlar" chiqsin, saqlangach yo'qolsin. Sahifa tepasigawire:offlinetasma qo'shing. Brauzer DevTools'ida tarmoqni "Offline" qilib (Network β Offline), tasma chiqishini tekshiring. Yo'naltirish:wire:dirtyso'rovsiz, faqat qiymat o'zgarishida yonadi. -
Skeleton ekranli ro'yxat (qiyin). Tugma bosilganda postlar ro'yxatini yuklaydigan (
usleepbilan 1 soniya sekinlashtirilgan) komponent yozing. Yuklash davomida kulrang skeleton bloklarni (wire:loading+wire:target), tugagach esa haqiqiy postlarni (wire:loading.remove+wire:target) ko'rsating..skeleton-lineuchun oddiy CSS yozing (kulrang fon, yumaloq burchak). Yo'naltirish: skeleton va kontent bloklari bir xilwire:targetga bog'lansin; keyingi bobda (#[Lazy]+placeholder()) buni yanada chiroyli qilamiz.
β¬ οΈ Oldingi: 19 β URL va query string Β· π Kitob boshi Β· Keyingi: 21 β Lazy, polling, navigatsiya β‘οΈ