في هذا المقال سيتم إضافة ميزه عمل فلترة للمقالات ( القسم، العنوان ....)، للقيام بذلك يجب ان نقوم بالبداية بتحضير backEnd بإضافة Category، ومن ثم عرضها في FrontEnd وعرضها في select box وعندما يتم تغيير قيمة selectbox ان يتم إعادة تحميل للبيانات مع تنفيذ الفلتر، بدون إعادة تحميل الصفحة لأننا نتعامل مع SPA.
php artisan make:model Category -mf
class Category extends Model { use HasFactory; protected $fillable = ['name']; }
public function up() { Schema::create('categories', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps(); }); }
class CategoryFactory extends Factory { protected $model = Category::class; public function definition() { return [ "name" => $this->faker->word(), ]; } }
هنا يلزم أن يتم التعديل على ملف Posts Migration حتى يتم إضافة category_id لأن كل مقال يتبع لقسم
php artisan make:migration add_category_id_to_posts_table
public function up() { Schema::table('posts', function (Blueprint $table) { $table->foreignId('category_id') ->constrained() ->onUpdate('cascade') ->onDelete('cascade'); }); }
class Post extends Model { use HasFactory; protected $fillable = ['title','body','category_id']; }
class PostFactory extends Factory { protected $model = Post::class; public function definition() { return [ "title" => $this->faker->word(), "body" => $this->faker->sentence(), "category_id" => Category::all()->random()->id, ]; } }
class DatabaseSeeder extends Seeder { public function run() { Category::factory(10)->create(); Post::factory(100)->create(); } }
php artisan migrate:fresh --seed
يجب إضافة category_id في PostResource الموجود في المسار app/Http/Resources/PostResource.php
class PostResource extends JsonResource { public function toArray($request) { return [ 'id'=> $this->id, 'title'=>$this->title, 'body'=>$this->body, 'category_id'=>$this->category_id, 'created_at'=>$this->created_at->toDateString(), ]; } }
php artisan make:resource CategoryResource
class CategoryResource extends JsonResource { public function toArray($request) { return parent::toArray($request); } }
هنا لن اقوم بالتعديل على الكلاس، فلا يوجد تعديل على الحقول،. فيتم إرجاع جميع الحقول
php artisan make:controller Api/CategoryController -r
بداخل الدالة index
class CategoryController extends Controller { public function index() { return CategoryResource::collection(Category::all()); } }
Route::get('posts', [PostController::class, 'index']); Route::get('category', [CategoryController::class, 'index']);
عند زيارتنا للرابط http://www.test.test/api/category فإنه يجب أن يتم عرض الأقسام
{ "data": [ { "id": 1, "name": "ullam", "created_at": "2021-08-04T09:13:33.000000Z", "updated_at": "2021-08-04T09:13:33.000000Z" }, ] }
بداخل Post Component نضيف وسم select
<select class="form-control col-3"> <option value="">--Choose Category--</option> <option v-for="category in categories" :value="category.id"> {{ category.name}} </option> </select>
بداخل script في data نعرف متغير categories وفي الدالة mounted نقوم بالإتصال مع api لجلب البيانات
<script> export default { data(){ return { posts:{}, categories:{}, } }, mounted() { axios.get('/api/category') .then(response => { this.categories = response.data.data; }); this.getResults(); }, methods:{ getResults(page = 1) { axios.get('/api/posts?page=' + page) .then(response => { this.posts = response.data; }); } } } </script>
عندما يختار المستخدم قسم معين، يجب أن يتم عرض المقالات التابعة لهذا القسم فقط، وللقيام بذلك نحتاج لإستخدام v-model ومن ثم إعطاءه متغير، بحيث يتم إستخدام هذا المتغير في data
<select v-model="category_id" class="form-control"> <option value="">--Choose Category--</option> <option v-for="category in categories" :value="category.id"> {{ category.name}} </option> </select>
وفي script بداخل الدالة data
data(){ return { posts:{}, categories:{}, category_id:'', } },
نحتاج للتعديل على دالة getResults بحيث يتم إرسال category_id
methods:{ getResults(page = 1) { axios.get('/api/posts?page=' + page + '&category_id='+this.category_id) .then(response => { this.posts = response.data; }); } }
نحتاج لإضافة الدالة watch حتى يتم مراقبة ما يحصل على select box فعند تغيير قيمتها تتنفذ الدالة
watch:{ category_id(value){ this.getResults() } },
توضيح:
عندما يتم تغييرر قيمة select box فإن v-model ترسل القيمة إلى المتغير category_id الموجود بداخل الدالة data، ثم الدالة watch تلاحظ هذا التغير فتقوم بطلب البيانات من الـ api بإسخدام الدالة getResults.
public function index() { $posts=Post::when(request('category_id','') !='',function ($q){ $q->where('category_id',request('category_id')); })->paginate(20); return PostResource::collection($posts); }
وبذلك تم تجهيز filter
Mohammed
ارجو ان يكون توضيح لكيفية استخدام paginate لاني استخدمت العديد من المكاتب