Laravel ကို ဘယ် Front-end နည်းပညာနဲ့မဆို တွဲဖက်အသုံးပြုလို့ရပါတယ်။ အဲ့ဒီလို တွဲဖက်အသုံးပြုလို့ရတဲ့ နည်းပညာတွေထဲက Livewire အကြောင်းကို တစ်ခါထဲ လက်တွေ့လိုက်လုပ်ကြည့်လို့ရမယ့် Tutorial ပုံစံနဲ့ ဖော်ပြသွားမှာပါ။ Livewire ကို အကျဉ်းချုပ်အားဖြင့် JavaScript တွေရေးစရာမလိုတော့ဘဲ PHP နဲ့ပဲ Sing-Page Application (SPA) တွေ ဖန်တီးလို့ရတဲ့ နည်းပညာလို့ ဆိုနိုင်ပါတယ်။
စမ်းသပ်ကြည့်နိုင်ဖို့အတွက် ပထမဆုံး Laravel ပရောဂျက် အသစ်တစ်ခုကို အခုလို တည်ဆောက်ယူလိုက်ပါ။
composer create-project laravel/laravel tall
နမူနာအရ tall
ဆိုတဲ့ ဖိုဒါအမည်နဲ့ Laravel ပရောဂျက်သစ်တစ်ခု ရရှိသွားပါလိမ့်မယ်။ ပရောဂျက်ဖိုဒါထဲကို cd tall
နဲ့ဝင်ပြီး Laravel Breeze ကို အခုလို Install လုပ်လိုက်ပါ။
composer require laravel/breeze --dev
Laravel Breeze ဟာ အသင့်သုံး User Authentication System ကို Tailwind တို့ Livewire တို့နဲ့ ရေးပေးထားတဲ့ Official Package တစ်ခုဖြစ်ပါတယ်။ ဒီ Package ကို Install လုပ်လိုက်ခြင်းအားဖြင့် User Authentication အပြင် Tailwind တို့ Livewire တို့လည်း တစ်ခါထဲ ထည့်သွင်းပါဝင်သွားပြီး ဖြစ်စေပါတယ်။ ကိုယ့်ဘာသာ တစ်ခုချင်း ထပ်ထည့်စရာ မလိုတော့ပါဘူး။
ပြီးတဲ့အခါ လိုအပ်တဲ့ Setup တွေ ပြုလုပ်စေဖို့အတွက် ဒီ Command ကို Run ပေးပါ။
php artisan breeze:install
လာမေးတဲ့ မေးခွန်းတွေထဲက Livewire with Alpine
ကို ရွေးပေးပါ။ ဒါဆိုရင် Livewire ကို အသုံးပြုပြီး လိုအပ်တဲ့ Setup တွေကို သူက လုပ်ပေးသွားမှာပါ။ ကျန်မေးခွန်းတွေကိုတော့ အခုထည့်ကြည့်မယ့်ထဲမှာ မပါသေးလို့ နှစ်သက်ရာသာ ရွေးလိုက်ပါ၊ ရပါတယ်။
ဆက်လက်ပြီး စမ်းကြည့်စရာ Data ရအောင် Migrate တွေ Seed တွေ လုပ်ကြပါမယ်။ အရင်ဆုံး .env
ဖိုင်မှာ DB_DATABASE=laravel
ကို DB_DATABASE=tall
လို့ ပြင်ပေးပြီး migrate Run ပေးလိုက်ပါ။
php artisan migrate
Migration Run စဉ်မှာ Database မရှိသေးလို့ ဆောက်မှာလားမေးရင် Yes
လို့ ရွေးပေးပါ။ ပြီးတဲ့အခါ Sample Data လေးတစ်ချို့ ထည့်ဖို့အတွက် database/seeders/DatabaseSeeder.php
မှာ Comment ပိတ်ထားတဲ့ ဒီလိုင်းလေးကို ဖွင့်ပေးလိုက်ပါ။
\App\Models\User::factory(10)->create();
Seed Run ပြီး Sample Data ထည့် လို့ရပါပြီ။
php artisan db:seed
Server တွေ Run ဖို့ရယ်၊ လိုအပ်တဲ့ Command Run ဖို့ရယ် Terminal (၃) ခုလိုပါမယ်။ Server တွေကို Background Service အနေနဲ့ Run ပြီး Manage လုပ်တတ်ရင်တော့ တစ်ခုထဲလည်း ရပါတယ်။ ဒါပေမယ့် ဒီနေရာမှာတော့ ရှင်းသွားအောင် (၃) ခုခွဲသုံးတယ်လို့သာ သဘောထားပါ။ အရင်ဆုံး Terminal တစ်ခုမှာ Client-side Dev Server ကို အခုလို Run လိုက်ပါ။
npm run dev
Run လက်စကို ပိတ်လိုက်လို့ မရပါဘူး။ ဒီအတိုင်း Run ထားရမှာပါ။ Terminal နောက်တစ်ခုနဲ့ PHP Dev Server ကို အခုလို Run လိုက်ပါ။
php artisan serve
သူလည်း Run လက်စကို ပိတ်လိုက်လို့ မရပါဘူး။ ဒီအတိုင်း ဆက် Run ထားရမှာပါ။ Browser မှာ localhost:8000 နဲ့ စမ်းကြည့်လို့ရပါပြီ။
ဆက်လက်ပြီး နောက် Terminal တစ်ခုမှာ အခုလို Run ပြီး လိုအပ်တဲ့ Livewire Component တွေ View တွေဖန်တီးလိုက်ပါ။
php artisan livewire:layout
php artisan make:livewire users.user-list
php artisan make:livewire users.user-detail
php artisan make:livewire users.user-add
ပထမ Command က resources/views/components/layouts/app.blade.php
အမည်နဲ့ Main Layout View ဖိုင်တစ်ခုကို တည်ဆောက်ပေးသွားမှာဖြစ်ပါတယ်။ Livewire Component တွေအတွက် Component Class ဖိုင်တွေကို app/Livewire
ထဲမှာ တည်ဆောက်ပေးသွားမှာ ဖြစ်ပြီး သူနဲ့တွဲဖက်သုံးဖို့အတွက် View ဖိုင်တွေကို resources/views/livewire
ထဲမှာ တည်ဆောက်ပေးသွားမှာ ဖြစ်ပါတယ်။ ဒါကြောင့် make:livewire
Command (၃) ခုကနေ ရရှိလာမယ့် ဖိုင်တွေက ဒီလိုပါ
app/Livewire/Users/UserList.php
resources/views/livewire/users/user-list.blade.php
app/Livewire/Users/UserDetail.php
resources/views/livewire/users/user-detail.blade.php
app/Livewire/Users/UserAdd.php
resources/views/livewire/users/user-add.blade.php
resources/views/components/layouts/app.blade.php
ထဲက ကုဒ်ကို အခုလိုပြင်ပေးလိုက်ပါ။
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Livewire</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<div class="min-h-screen bg-gray-100">
<header class="bg-white shadow">
<div class="flex max-w-5xl mx-auto py-6 px-4">
<h2 class="font-semibold text-xl
text-gray-800 leading-tight">
Livewire
</h2>
<a class="text-green-600 ms-6"
href="/users/add" wire:navigate>+ Add User</a>
</div>
</header>
<main class="max-w-3xl mx-auto py-6 px-4">
{{ $slot }}
</main>
</div>
</body>
</html>
ဒီဖိုင်က Livewire Component တွေကို Full Page Component အနေနဲ့ ပြတဲ့အခါ Main Template အဖြစ် အသုံးပြုပေးမယ့်ဖိုင် ဖြစ်ပါတယ်။ အဓိကထူးခြားချက် နှစ်ချက်ပဲပါပါတယ်။ $slot
နေရာမှာ Component ကို လာပြမှာဖြစ်ပြီး၊ <a>
Element မှာ wire:navigate
Attribute ပါသွားပါတယ်။ ဒါကြောင့် ဒီ <a>
Element ကို နှိပ်တဲ့အခါ နောက်တစ်မျက်နှာအနေနဲ့ Page Reload နဲ့ မသွားတော့ဘဲ သက်ဆိုင်ရာ Component ကို နေရာမှာတင် Single-page အနေနဲ့ ပြောင်းပြီး ပြပေးသွားမှာပါ။ JavaScript တွေမလိုဘဲ PHP နဲ့ပဲ Single-page အလုပ်လုပ်အောင် ရေးလို့ရတယ်ဆိုတာ ဒီသဘောကို ပြောတာပါ။
ပြီးတဲ့အခါ app/Livewire/User/UserList.php
မှာ အခုလို ရေးပေးပါ။
<?php
namespace App\Livewire\Users;
use App\Models\User;
use Livewire\Component;
class UserList extends Component
{
public function render()
{
return view('livewire.users.user-list', [
"users" => User::all()
]);
}
}
နဂို Auto-generated Code ကို နည်းနည်းပဲ ပြင်ထားပါတယ်။ render()
Method မှာ View ကို ပြန်ပေးတဲ့အခါ User
Model ကိုသုံးပြီး Seed လုပ်ထားတဲ့ Sample User တွေကိုပါ ထည့်ပေးလိုက်တာပါ။ ဒါက Component Class ပဲ ရှိပါသေးတယ်။ Component View ကို resources/views/livewire/users/user-list.blade.php
မှာ အခုလို ရေးပေးလိုက်ပါ။
<ul class="mt-4">
@foreach ($users as $user)
<li class="border-b py-2 mb-2 flex justify-between"
wire:key="{{ $user->id }}">
<a href="/users/view/{{ $user->id }}"
class="text-blue-700" wire:navigate>
{{ $user->name }}
</a>
<button wire:click="delete({{ $user->id }})"
class="text-red-500 text-xl font-bold">
×
</button>
</li>
@endforeach
</ul>
သိပ်ရှုပ်ရှုပ်ယှက်ယှက် မဟုတ်ပါဘူး။ $users
တွေကို Loop လုပ်ပြီး ပြထားလိုက်တာပါပဲ။ ကြည့်ကောင်းအောင် Tailwind Class တွေသုံးထားပေမယ့် အဓိကပိုကျတာက wire:key
wire:navigate
wire:click
ဆိုတဲ့ Attribute တွေပါ။
wire:key
ရဲ့ သဘောကိုတော့ React တို့ Vue တို့ လေ့လာဖူးသူတွေ သိကြပါလိမ့်မယ်။ Loop လုပ်ထားတဲ့ Item တွေမှာ Unique ဖြစ်တဲ့ Key Attribute ရှိမှသာ နောက်ပိုင်း အပြောင်းအလဲ ရှိတဲ့အခါ List တစ်ခုလုံးကို အစအဆုံး ပြန်ပြီး Render လုပ်စရာမလိုဘဲ လိုတဲ့အပိုင်းလေးပဲ ရွေးပြီး လုပ်လို့ရစေဖို့ ဖြစ်ပါတယ်။
wire:navigate
ရဲ့သဘော အကျဉ်းချုပ်ကို အပေါ်မှာ ပြောခဲ့ပြီးပါပြီ။ wire:click
ကတော့ Button ကို နှိပ်တဲ့အချိန်မှာ Run စေချင်တဲ့ Function (Component Method) ကို ပေးရတာပါ။ ပုံမှန်အားဖြင့် Button Click မှာ PHP ကုဒ်တွေ Run လို့မရပါဘူး။ Client-side, Server-side တူမှ မတူတာကိုး။ Run ချင်ရင် JavaScript ကုဒ်တွေဘဲ Run လို့ရမှာပါ။ Livewire က wire:click
နဲ့ Button Click မှာ PHP ကုဒ်တွေ Run လို့ရအောင် လုပ်ပေးလိုက်တာပါ။ လောလောဆယ် ခေါ်ထားတဲ့ delete()
Method က မရှိသေးပါဘူး။ နောက်မှရေးမှာပါ။ ကြိုခေါ်ထားလိုက်တာပါ။
ဆက်လက်ပြီး စတင်စမ်းသပ်နိုင်ဖို့အတွက် routes/web.php
မှာ အခုလို Component တွေကို Import လုပ်ပြီး Route တစ်ချို့ ရေးထည့်ပေးလိုက်ပါ။
use App\Livewire\Users\UserAdd;
use App\Livewire\Users\UserDetail;
use App\Livewire\Users\UserList;
Route::get('/users', UserList::class);
Route::get('/users/view/{id}', UserDetail::class);
Route::get('/users/add', UserAdd::class);
ပုံမှန်အားဖြင့် Route ကနေ Controller တွေ View တွေကို လှမ်းချိတ်မှာပါ။ အခုတော့ Controller တွေ View တွေကို မချိတ်တော့ဘဲ စောစောက ရေးထားတဲ့ UserList
Component ကို တိုက်ရိုက် လှမ်းချိတ်လိုက်တာပါ။ ဒါကြောင့် /users
Route ကို သွားလိုက်ရင် UserList
Component ကို Layout ထဲမှာ ထည့်ပြီး Full-page Component အနေနဲ့ ပြပေးလာမှာ ဖြစ်ပါတယ်။
ကျန်တဲ့ UserDetail
တွေ UserAdd
တွေ ထပ်မရေးခင် ဒီအဆင့်မှာတင် စတင်စမ်းသပ်ကြည့်လို့ရပါပြီ။
localhost:8000/users ကိုသွားကြည့်လိုက်ရင် အခုလိုရလဒ်ကို ရရှိမှာဖြစ်ပါတယ်။ Database Table ထဲက Users တွေကို UserList
Livewire Component နဲ့ လာပြပေးနေခြင်းပဲ ဖြစ်ပါတယ်။
User Delete လုပ်တာကတော့ လွယ်လွယ်လေးပါ။ wire:click
နဲ့ Function ခေါ်ထားပြီးသားမို့လို့ UserList
Class မှာ အခုလို Method တစ်ခု ထပ်တိုးပေးလိုက်ယုံပါပဲ။
public function delete($id)
{
$user = User::find($id);
$user->delete();
}
ရေးရိုးရေးစဉ်အတိုင်း User
Model ကိုသုံးပြီး ဖျက်လိုက်တာပါ။ Livewire က delete()
ကို ခေါ်ပေးတဲ့အပြင် React တို့ဘာတို့မှာ State ပြောင်းရင် Component လိုက်ပြောင်းပေးနိုင်သလိုပဲ Server-side ဘက်မှာ Data ပျက်သွားယုံသာမက Client-side List ကလည်း Page Refresh တွေဘာတွေ မလိုဘဲ အလိုအလျှောက် Update ဖြစ်သွားမှာ ဖြစ်ပါတယ်။
ဆက်လက်ပြီး resources/views/livewire/users/user-detail.blade.php
မှာ အခုလိုရေးပေးပါ။
<div class="border rounded p-4">
<h3 class="text-2xl mb-2">{{ $user->name }}</h3>
<p class="text-gray-600 mb-2">{{ $user->email }}</p>
<div class="mb-4">
<small class="text-gray-400">
{{ $user->created_at->diffForHumans() }}
</small>
</div>
<a href="/users" class="text-blue-500"
wire:navigate>« Go back</a>
</div>
ဒီကုဒ်က သိပ်စိတ်ဝင်စားစရာ မကောင်းလှပါဘူး။ wire:navigate
နဲ့ Link တစ်ခုပါပေမယ့် အခြေခံအားဖြင့် $user
Data တွေကို Box လေးတစ်ခုနဲ့ ပြလိုက်တာပါပဲ။ ဒါပေမယ့် ဒီလိုပြနိုင်ဖို့အတွက် UserDetail
Class မှာ အခုလိုရေးပေးဖို့ လိုပါတယ်။
<?php
namespace App\Livewire\Users;
use App\Models\User;
use Livewire\Component;
class UserDetail extends Component
{
public $user;
public function mount($id)
{
$this->user = User::find($id);
}
public function render()
{
return view('livewire.users.user-detail');
}
}
ဒီမှာတော့ သတိပြုရမှာတွေပါလာပါပြီ။ ပထမဆုံး $user
Property ကို ကြေညာထားပါတယ်။ ဒါကြောင့် View မှာ $user
ကို အသုံးပြုလို့ရသွားပါပြီ။ ပြီးတဲ့အခါ mount()
Method ကို သုံးပြီး User
Model ရဲ့ အကူအညီနဲ့ User Data တွေထုတ်ယူထားပါတယ်။ ရလာတဲ့ Data တွေကို $user
Property ထဲမှာ ထည့်ပေးလိုက်တာပါ။
ဒီနေရာမှာ Data ထုတ်ယူတဲ့ကုဒ်ကို render()
မှာ မရေးဘဲ mount()
မှာရေးတာက $id
URL Parameter ကို လိုချင်လို့ပါ။ Route မှာ /users/view/{id}
လို့ သတ်မှတ်ထားတဲ့အတွက် Controller Method တွေမှာ $id
ကို ယူသုံးလို့ရသလိုပဲ mount()
မှာလည်း ယူသုံးလို့ရပါတယ်။ mount()
Method ဟာ Livewire ရဲ့ Lifecycle Method တွေထဲကတစ်ခုဖြစ်ပြီး Component ကို Render လုပ်တဲ့အချိန်တိုင်းမှာ အလိုအလျှောက် အလုပ်လုပ်တဲ့ Method တစ်ခုပါ။
ဒီလောက်ဆိုရင် User View လည်းရသွားပါပြီ။ List ထဲက User တစ်ယောက်ကို နှိပ်လိုက်ရင် Page Reload မလိုအပ်ဘဲ UserDetail
Component ကို ပြပေးသွားမှာဖြစ်သလို၊ UserDetail
က Go Back Link ကို နှိပ်လိုက်ရင်လည်း Page Reload မလိုဘဲ UserList
ကို ပြန်ပြပေးသွားပါလိမ့်မယ်။
User တွေအသစ်ထပ်ထည့်ဖို့အတွက် Form Template တစ်ခုလိုပါမယ်။ resources/views/livewire/users/user-add.blade.php
မှာ အခုလိုရေးပေးပါ။
<form wire:submit="save">
<input type="text" wire:model="name"
class="w-full border rounded p-3"
placeholder="Name">
<div class="text-red-600 text-sm mb-3">
@error('name') {{ $message }} @enderror
</div>
<input type="text" wire:model="email"
class="w-full border rounded p-3"
placeholder="Email">
<div class="text-red-600 text-sm mb-3">
@error('email') {{ $message }} @enderror
</div>
<button type="submit"
class="rounded bg-blue-700 text-white py-2 px-6">
Add User
</button>
</form>
Validation Message တွေပါ ထည့်ပြထားလို့ နည်းနည်းရှုပ်သွားတယ်ထင်ရပေမယ့်၊ သေချာကြည့်ရင် သိပ်မရှုပ်ပါဘူး။ Name နဲ့ Email ကို Input နှစ်ခုနဲ့ တောင်းထားတဲ့ HTML Form တစ်ခုသာဖြစ်ပါတယ်။ အရေးအကြီးဆုံး ထူးခြားချက်ကတော့ <form>
မှာ wire:submit
နဲ့ save()
ကို ခေါ်ထားခြင်းဖြစ်ပါတယ်။ ဒါကြောင့် ဒီ Form မှာ Submit နှိပ်လိုက်ရင် Page Reload နဲ့ Server Submit မလုပ်တော့ဘဲ UserAdd
Class ရဲ့ save()
Method ကို ခေါ်ပေးသွားမှာဖြစ်ပါတယ်။
နောက်ထပ်အရေးကြီးတာကတော့ Input တွေမှာပါတဲ့ wire:model
ဖြစ်ပါတယ်။ လိုရင်းကတော့ Input ကို Class Property နဲ့ ချိတ်ပေးလိုက်တာပါ။ ဒါကြောင့် ဒီ Input တွေမှာ ရေးဖြည့်လိုက်သမျှ သက်ဆိုင်ရာ $name
နဲ့ $email
Property တွေထဲကို အလိုအလျှောက် ရောက်သွားမှာပါ။
Blade @error
Directive နဲ့ Validation Error ရှိမရှိစစ်ပြီး ရှိရင် တစ်ခါထဲ ပြခိုင်းထားပါတယ်။ ဒီ Form အလုပ်လုပ်ဖို့အတွက် လိုအပ်တဲ့ ကုဒ်တွေကို UserAdd
Class မှာ အခုလို ရေးပေးပါ။
<?php
namespace App\Livewire\Users;
use App\Models\User;
use Livewire\Attributes\Rule;
use Livewire\Component;
class UserAdd extends Component
{
#[Rule('required')]
public $name = '';
#[Rule('required|email')]
public $email = '';
public function save()
{
$this->validate();
User::factory()->create([
"name" => $this->name,
"email" => $this->email,
]);
$this->reset();
return redirect("/users");
}
public function render()
{
return view('livewire.users.user-add');
}
}
$name
နဲ့ $email
Property နှစ်ခုရှိတာကို သတိပြုကြည့်ပါ။ Property တွေကြေညာတဲ့အခါ Validation Attribute တွေနဲ့ Validation Rules တွေကို တစ်ခါထဲ ထည့်ရေးပြီး ကြေညာထားပါတယ်။ ဒါကြောင့် save()
Method မှာ $this->validate()
ကိုခေါ်လိုက်တဲ့အခါ သက်မှတ်ထားတဲ့ Rule များအတိုင်း Validation စစ်ပြီး Fails ဖြစ်ခဲ့ရင် ဆက်မလုပ်ဘဲ Validation Error တွေနဲ့ Component ကို ပြန်ပြပေးမှာ ဖြစ်ပါတယ်။
Validation Pass ဖြစ်ခဲ့ရင်တော့ User
Model ရဲ့ Factory အကူအညီနဲ့ User အသစ် Create လုပ်လိုက်ပါတယ်။ Factory ကိုသုံးရတာက User အတွက် Password အပါအဝင် တစ်ခြားလိုအပ်တာတွေ ထည့်မပေးလိုတဲ့အတွက် ပေးချင်တဲ့ Name နဲ့ Email ကိုပဲ ပေးပြီး ကျန် Value တွေကို Factory မှာ သတ်မှတ်ထားတဲ့အတိုင်း ထည့်ပေးလိုက်စေချင်လို့ပါ။ Name တို့ Email တို့ကို Property တွေကနေ ရပါတယ်။ Property တွေက Input Value တွေပါပဲ။ wire:model
နဲ့ချိတ်ပေးထားလို့ပါ။
$this->reset()
က Property Value တွေကို ပြန် Clear လုပ်လိုက်တာပါ။ နောက်ဆုံးမှာ redirect()
နဲ့ /users
Route ကို ပြန်သွားခိုင်းတဲ့အခါ ထုံးစံအတိုင်း Livewire က Page Reload ပြန်မလုပ်တော့ဘဲ /users
Route နဲ့ ချိတ်ထားတဲ့ UserList
Component ကို ပြန်ပြပေးသွားမှာပဲ ဖြစ်ပါတယ်။
ဒီလောက်ဆိုရင် Livewire ရဲ့ အလုပ်လုပ်ပုံကို တော်တော်လေး သဘောပေါက်သွားလောက်ပြီလို့ ယူဆပါတယ်။ အလားတူလုပ်ဆောင်ချက်မျိုးရဖို့အတွက် JavaScript Framework တစ်ခုခုကိုသုံးပြီး ရေးရင်လည်း ရနိုင်ပေမယ့်၊ Back-end သပ်သပ် Front-end သပ်သပ် ခွဲပြီး Maintain လုပ်စရာမလိုတော့သလို API Call တွေကိုလည်း Management လုပ်စရာမလိုတော့ပါဘူး။ တစ်ချို့က သပ်သပ်စီ ခွဲရေးရတာကို နှစ်သက်နိုင်ပေမယ့် အခုလို Language တစ်မျိုးထဲနဲ့ Laravel Framework ထဲကနေ ထွက်စရာမလိုဘဲ စီမံရေးသားနိုင်ခြင်းဟာလည်း အသုံးဝင်တဲ့ နည်းပညာတစ်ခုပဲ ဖြစ်ပါတယ်။
နိဂုံးချုပ်အနေနဲ့ သတိပြုစေချင်တဲ့ အချက်ကတော့ လက်ရှိနမူနာကုဒ်မှာ M-V-C ရဲ့ C (ခေါ်) Controller လုံးဝ ပြုတ်သွားခြင်းပါပဲ။ Controller ကုဒ်တွေ ရေးရိုးရေးစဉ်အတိုင်း ဆက်ရေးလို့လည်း ရပါတယ်။ API ကုဒ်တွေပါမယ်ဆို မဖြစ်မနေ ထည့်ရေးရမှာပါ။ ဒါပေမယ့် အခုလို UI ပိုင်းအတွက်တော့ Controller မလိုအပ်ရင် မသုံးတော့ဘဲ Component ချင်း ချိတ်ဆက်ရေးသားသွားတယ်ဆိုတာ သတိပြုရမှာပဲ ဖြစ်ပါတယ်။
Thanks a lot!