در این مقاله به آموزش استفادهی یکی از بهترین امکانات لاراول یعنی View Composer میپردازیم.
فرض کنید میخواهید تعداد زیادی از دادههای database را در صفحات مختلف سایت به کاربر نمایش دهید. سادهترین راه این است که در Controller دادهها را از Model بگیریم و به View ارسال کنیم. این کار تا زمانی که تعداد صفحات سایت کم باشد، تقریبا راهی معقول است. اما زمانی که سایت ما گسترش یابد، با مشکلاتی روبرو میشویم که به یک راه جایگزین نیاز پیدا میکنیم. این راه همان استفاده از View Composer است که در ادامه برای درک بهتر تفاوتها ابتدا راه معمولی را میگوییم، سپس آن را با View Composer مقایسه میکنیم. همچنین برای تفهیم بیشتر View Composer در لاراول مطالب یک پروژهی کوچک که میخواهد نام چند ماشین را نمایش دهد، پیادهسازی میکنیم.
راه معمولی :
روشی که ما در این آموزش به آن میپردازیم. ابتدا ساخت route، سپس controller و بعد از آن view است.
ساخت Route :
برای ساخت یک route در آدرس routes/web.php بهصورت زیر عمل میکنیم.
<?php
use Illuminate\Support\Facades\Route;
Route::get('cars','CarsController@index');
ساخت Controller :
توسط دستور زیر یک Controller بهنام CarsController را ایجاد میکنیم.
$ php artisan make:controller CarsController
همان طور که مشاهده میکنید، برای نمایش دادهها route به CarsController میرود و تابع index را میخواند. پس تابع index را در CarsController ایجاد میکنیم و نام تمام ماشینها که از قبل در database ایجاد کردیم را از Model میگیریم و به یک View ارسال میکنیم.
<?php
namespace App\Http\Controllers;
use App\Cars;
use Illuminate\Http\Request;
class CarsController extends Controller
{
public function index()
{
$cars=Cars::all();
return view('cars.index',compact('cars'));
}
}
توجه کنید که حتما model خود را در بالا use کرده باشید.
ساخت View :
اگر به تابع index در Controller توجه کرده باشید، میبینید که cars به یک View بهنام cars.index توسط تابع compact ارسال میشود. پس در این مرحله به ساخت View میپردازیم.
برای ساخت View ابتدا پوشهای بهنام cars در resources/views میسازیم. سپس فایل blade بهنام index را بهصورت زیر ایجاد میکنیم.
حال در صفحهی سایتمان نام تمام ماشينها به صورت زیر نمايش داده میشود، که این همان راه معمولی و همیشگی است.
همانطور که مشاهده کردید، ما فقط برای یک صفحه از سایت یعنی صفحهی cars/ نیاز به ساخت Controller و سپس View داریم. فرض کنید که سایت ما دارای ۲۰ صفحه است که در تمام آن صفحات باید نام ماشینها، بهطور مثال در یک صفحه بهترتیب قیمت، در صفحهی دیگر بهترتیب سال تولید و در صفحات مختلف به ترتیبهای دیگری نمایش داده شود. در این صورت ساخت حداقل یک Controller برای هر کدام از آنها دیگر بهترین راه نیست و View Composer بهترین جایگزین است.
انتقال دادهها بهصورت Global :
برای آشنایی با View Composer ابتدا میخواهیم یاد بگیریم که چگونه میتوانیم دادهها را به جای چند Controller تنها در یک قسمت وارد کنیم تا تمام Viewها به آن دسترسی داشته باشند.
برای اینکار به app/Providers/AppServiceProvider.php بروید و در تابع boot دستور زیر را وارد کنید.
<?php
namespace App\Providers;
use App\Cars;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
View::share('cars', Cars::orderBy('name')->get());
}
public function register()
{
//
}
}
ما از کلاس View، متد share را فراخوانی کردیم که پارامتر اول آن نام متغیر یعنی cars$ و پارامتر دوم مقدار cars$ است. (توجه کنید که از علامت $ در پارامترها استفاده نکنید.)
حال اگر در CarsController خط زیر و مقدار compact را پاک کنید و به صفحهی سایت بروید، مشاهده میکنید که تمامی دادهها مثل قبل، البته بهترتیب نام وجود دارند.
مشکلات این روش :
وقتی که یک متغیر را بهصورت بالا در AppServiceProvider و بهصورت Global تعریف میکنیم. بهطور خودکار این متغیر بهتمام Viewها چه بخواهیم، چه نخواهیم ارسال میشود و این کار database را بیهوده اشغال میکند.
[ltitle]View Composer در لاراول :[/ltitle]
View Composer مانند روش بالاست با این تفاوت که میتوانیم تعیین کنیم که متغیرمان به کدام Viewها ارسال شود.
<?php
namespace App\Providers;
use App\Cars;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
// Option 2
View::composer(['cars.index','cars.buy'], function($view)
{
$view->with('cars', Cars::orderBy('name')->get())
});
}
public function register()
{
//
}
}
ما از کلاس View، متد composer را فراخوانی کردیم که پارامتر اول آن صفحاتی که میخواهیم متغیر به آن ارسال شود و پارامتر دوم یک تابع callback است که مانند View::share عمل میکند و میتوانید همان اطلاعاتی که در View::share وارد کردید در with هم وارد کنید.
همچنین اگر میخواهید بهطور مثال متغیر به تمام Viewهای درون یک پوشه ارسال شود کافی است بهجای نام یک View علامت * را بهصورت زیر بگذارید.
حال اگر بهطور مثال بخواهیم که دادهها در یک صفحه بهترتیب نام، در صفحهای دیگر بهترتیب قیمت، و در هر صفحه به شکل خاصی مرتب شوند میتوانیم در app/Http یک پوشه بهنام View بسازیم و در آن پوشهای بهنام Composers ایجاد کنیم. بعد از ایجاد پوشهی Compossers در آن یک Class بهنام CarsComposer بسازید و درون CarsComposer کد زیر را وارد کنید :
<?php
namespace App\Http\View\Composers;
use App\Cars;
use Illuminate\View\View;
class CarsComposser
{
public function compose(View $view)
{
$view->with('cars', Cars::all());
}
}
همان دستوراتی که در تابع callback هنگام استفاده از View::composer وارد کردیم را در تابع compose کلاس بالا تعریف میکنیم. سپس به AppServiceProvider رفته و View::composer را بهصورت زیر تغییر میدهیم :
<?php
namespace App\Providers;
use App\Cars;
use App\Http\View\Composers\CarsComposser;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
//Option 3
View::composer(['cars.index','cars.buy'],CarsComposser::class);
}
public function register()
{
//
}
}
همچنین امكان دارد چندین View مختلف، در چندین پوشهی مختلف قرار داشته باشد. بهطور مثال فرض کنید که شما ۱۰ پوشه که در هر پوشه ۵ View قرار دارد را دارید. در این صورت وارد کردن Viewها کاری تقریبا زمانبر است. پس بهتر است از راه جایگزین استفاده کنید. بدین منظور قسمتهایی از View که دارای متغیر cars میباشد یعنی:
@foreach($cars as $car)
<li>{{ $car->name }}</li>
@endforeach
را به پوشهای مانند پوشهی partials میبریم و در view خود آن را include میکنیم.
public function boot()
{
//Option 3
View::composer(['cars.index','cars.buy'],CarsComposser::class);
}
به
public function boot()
{
//Option 3
View::composer('partials.*',CarsComposser::class);
}
تغییر میدهیم.
جمعبندی:
در این مقاله سعی ما از ابتدا بر این بود، که مفاهيم را هر چه بهتر و در قالب یک پروژهی کوچک، همراه با مقایسه نسبت به روشهای دیگر به شما آموزش بدهیم. حال شما میتوانید از این قابلیت بزرگ لاراول در پروژههای خود همانگونه که میخواهید استفاده کنید. در صورت داشتن هرگونه سوال یا تجربهای در این زمینه، آن را در قسمت نظرات با ما به اشتراک بگذارید.
اگر به یادگیری بیشتر لاراول علاقه داری میتونی در دوره آموزش لاراول کاربردی (بسته پروژه محور) شرکت کنی، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژهها به صورت کامل برنامه نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.
سلام عالی بود واقعا ، ممنون فقط یه سوال وقتی میخوایم که همون ماشینها یکی بر اساس رنگ یکی نوع یا یکی بر اساس اسمشون نمایش داده بشن اومدیم یه کلاس تعریف کردیم و داخلش همشو گرفتیم
بعد برای رنگ و نوع و اسم و مابقی باید متدهای مختلف رو داخل همین کلاس تعریف کنیم راه درستش همینه؟
علی مجیدی۲۸ خرداد ۱۳۹۹، ۱۳:۱۷
سلام ممنون از نظر لطف شما
بله شما میتونید Methodهای مختلف برای همون مرتبسازی بر اساس رنگ یا هر مشخصات دیگهای رو با استفاده از Queryها و Collectionها ایجاد کنید و وقتی که میخواید ماشینها براساس رنگ مشخص بشن علاوه بر Method ,Class موردنظرتون رو هم Call کنید.
سهیل۲۸ خرداد ۱۳۹۹، ۰۷:۵۳
سلام عالی بود واقعا ، ممنون فقط یه سوال وقتی میخوایم که همون ماشینها یکی بر اساس رنگ یکی نوع یا یکی بر اساس اسمشون نمایش داده بشن اومدیم یه کلاس تعریف کردیم و داخلش همشو گرفتیم
اینجا $view->with('cars', Cars::all());
بعد برای رنگ و نوع و اسم و مابقی باید متدهای مختلف رو داخل همین کلاس تعریف کنیم یعنی راه درستش همینه؟
مهرزاد۰۲ خرداد ۱۳۹۹، ۰۹:۴۱
بسیار عالی ....
علی مجیدی۰۲ خرداد ۱۳۹۹، ۱۰:۰۸
ممنون از نظر لطف شما
Mohsen Torabi۳۰ اردیبهشت ۱۳۹۹، ۰۴:۱۷
مثل مقاله ی قبلیتون عالی و بدون نقص ممنونم ازتون بابت وقتی که میذارید
علی مجیدی۳۰ اردیبهشت ۱۳۹۹، ۰۵:۵۶
ممنون از شما بابت نظر لطفتان ????
محمد جمالی۲۶ اردیبهشت ۱۳۹۹، ۱۸:۰۳
خیلی خوب بود مرسی????
علی مجیدی۲۶ اردیبهشت ۱۳۹۹، ۲۰:۳۸
ممنون از نظر لطف و همراهی شما
Saba vahedi۲۴ اردیبهشت ۱۳۹۹، ۲۱:۱۱
خیلی جامع و کامل بود تشکر از سایت خوبتون بابت مطالب کاربردی و خوبی که میزارید واقعا به این سایت علاقه مند شدم
علی مجیدی۲۵ اردیبهشت ۱۳۹۹، ۰۱:۴۴
ممنون از لطف شما ??
شروع رایگان یادگیری برنامه نویسی
کلیک کنید 👇
دوره الفبای برنامه نویسی با هدف انتخاب زبان برنامه نویسی مناسب برای شما و پاسخگویی به سوالات متداول در شروع یادگیری موقتا رایگان شد: