پرش به محتوای اصلی
مهارت های نرم

آموزش View Composer در لاراول

Ali Majidi Ali Majidi — دقیقه مطالعه ۴,۸۱۶ بازدید
آموزش View Composer در لاراول
در این مقاله به آموزش استفاده ی یکی از بهترین امکانات لاراول یعنی View Composer می پردازیم. فرض کنید می خواهید تعداد زیادی از داده های database را در صفحات مختلف سایت به کاربر نمایش دهید. ساده ترین راه این است که در Controller داده ها را از Model بگیریم و به View ارسال کنیم. این کار تا زمانی که تعداد صفحات سایت کم باشد، تقریبا راهی معقول است. اما زمانی که سایت ما گسترش یابد، با مشکلاتی روبرو می شویم که به یک راه جایگزین نیاز پیدا می کنیم. این راه همان استفاده از View Composer است که در ادامه برای درک بهتر تفاوت ها ابتدا راه معمولی را می گوییم، سپس آن را با View Composer مقایسه می کنیم. همچنین برای تفهیم بیشتر View Composer در لاراول مطالب یک پروژه ی کوچک که می خواهد نام چند ماشین را نمایش دهد، پیاد ه سازی می کنیم.

راه معمولی :

Waysروشی که ما در این آموزش به آن می پردازیم. ابتدا ساخت 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 را به صورت زیر ایجاد می کنیم.
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Cars</title>
</head>
<body>

<ul>
   @foreach($cars as $car)
       <li>{{ $car->name }}</li>
    @endforeach
</ul>

</body>
</html>

نمايش داده ها در سایت :

حال در صفحه ی سایت مان نام تمام ماشين ها به صورت زیر نمايش داده می شود، که این همان راه معمولی و همیشگی است. List همان طور که مشاهده کردید، ما فقط برای یک صفحه از سایت یعنی صفحه ی 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 علامت * را به صورت زیر بگذارید.
View::composer(['cars.*'], function($view)
        {
            $view->with('cars', Cars::orderBy('name')->get())
        });
حال اگر به طور مثال بخواهیم که داده ها در یک صفحه به ترتیب نام، در صفحه ای دیگر به ترتیب قیمت، و در هر صفحه به شکل خاصی مرتب شوند می توانیم در 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 می کنیم.
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Cars</title>
</head>
<body>

<ul>
@include('partials.list')
</ul>

</body>
</html>
سپس appServiceProvider را از
public function boot()
    {
        //Option 3

        View::composer(['cars.index','cars.buy'],CarsComposser::class);
    }
به
public function boot()
    {
        //Option 3

        View::composer('partials.*',CarsComposser::class);
    }
تغییر می دهیم. جمع بندی: در این مقاله سعی ما از ابتدا بر این بود، که مفاهيم را هر چه بهتر و در قالب یک پروژه ی کوچک، همراه با مقایسه نسبت به روش های دیگر به شما آموزش بدهیم. حال شما می توانید از این قابلیت بزرگ لاراول در پروژه های خود همان گونه که می خواهید استفاده کنید. در صورت داشتن هرگونه سوال یا تجربه ای در این زمینه، آن را در قسمت نظرات با ما به اشتراک بگذارید.
اگر به یادگیری بیشتر لاراول علاقه داری می تونی در دوره آموزش لاراول کاربردی (بسته پروژه محور) شرکت کنی، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژه ها به صورت کامل برنامه نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.
اشتراک‌گذاری:
۱۸ دیدگاه
Ali Majidi
نویسنده Ali Majidi
۴.۹

دیدگاه‌ها

۱۷ نفر تجربه‌شان را نوشته‌اند.

S
Saba vahedi ۱۳۹۹/۲/۲۵

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

ع
علی مجیدی ۱۳۹۹/۲/۲۵

ممنون از لطف شما ??

م
محمد جمالی ۱۳۹۹/۲/۲۶

خیلی خوب بود مرسی????

ع
علی مجیدی ۱۳۹۹/۲/۲۷

ممنون از نظر لطف و همراهی شما

M
Mohsen Torabi ۱۳۹۹/۲/۳۰

مثل مقاله ی قبلیتون عالی و بدون نقص ممنونم ازتون بابت وقتی که میذارید

ع
علی مجیدی ۱۳۹۹/۲/۳۰

ممنون از شما بابت نظر لطفتان ????

م
مهرزاد ۱۳۹۹/۳/۲

بسیار عالی ....

ع
علی مجیدی ۱۳۹۹/۳/۲

ممنون از نظر لطف شما

س
سهیل ۱۳۹۹/۳/۲۸

سلام عالی بود واقعا ، ممنون فقط یه سوال وقتی میخوایم که همون ماشین ها یکی بر اساس رنگ یکی نوع یا یکی بر اساس اسمشون نمایش داده بشن اومدیم یه کلاس تعریف کردیم و داخلش همشو گرفتیم
اینجا $view-&gt;with('cars', Cars::all());
بعد برای رنگ و نوع و اسم و مابقی باید متد های مختلف رو داخل همین کلاس تعریف کنیم یعنی راه درستش همینه؟

س
سهیل محمد بیگی ۱۳۹۹/۳/۲۸

سلام عالی بود واقعا ، ممنون فقط یه سوال وقتی میخوایم که همون ماشین ها یکی بر اساس رنگ یکی نوع یا یکی بر اساس اسمشون نمایش داده بشن اومدیم یه کلاس تعریف کردیم و داخلش همشو گرفتیم
بعد برای رنگ و نوع و اسم و مابقی باید متد های مختلف رو داخل همین کلاس تعریف کنیم راه درستش همینه؟

ع
علی مجیدی ۱۳۹۹/۳/۲۸

سلام ممنون از نظر لطف شما
بله شما می‌تونید Method های مختلف برای همون مرتب‌سازی بر اساس رنگ یا هر مشخصات دیگه‌ای رو با استفاده از Query ها و Collection ها ایجاد کنید و وقتی که می‌خواید ماشین‌ها براساس رنگ مشخص بشن علاوه بر Method ,Class موردنظرتون رو هم Call کنید.

ا
امیر ابوالفضل پور ۱۳۹۹/۱۱/۱۰

خیلی عالی بود ممنون

م
مهدی ۱۴۰۰/۲/۲۵

خیلی ممنون از لطف شما برای این آموزش

د
دانیال ۱۴۰۰/۷/۲۵

سوالم رو به طور کامل پاسخ داد این مقاله ،
عالی

ن
نازنین کریمی مقدم ۱۴۰۰/۷/۲۵

ممنون که با ما همراه هستید :)

۱۴۰۰/۱۰/۲۸

بسیار عالی

۱۴۰۱/۵/۳

ممنونم از مقاله خوبتون.
موفق باشید