Як передати дані всім переглядам у Laravel 5?


125

Я хочу, щоб у моїй програмі Laravel 5 доступні деякі дані за замовчуванням.

Я намагався знайти його , але тільки знайти результати для Laravel 4. Я прочитав документацію «Обмін даними з усіма Переглядів : » тут , але я не можу зрозуміти , що робити. Де слід розмістити наступний код?

View::share('data', [1, 2, 3]);

Спасибі за вашу допомогу.


ну, вам потрібен стартовий код для управління цією вимогою?
Safoor Safdar

1
голова вгору за допомогою View :: share у постачальника послуг з результатами виклику баз даних буде помилкою програми під час запуску оновлення db міграції або спроби запустити сутінки з недоступним db-з'єднанням (довга історія, .env.dusk.local є використовується лише після запуску постачальника послуг). Як було сказано нижче, базовий контролер або середнє програмне забезпечення є найкращим.
Енді Лобель

Також будьте обережні при використанні *композиторів перегляду, особливо якщо ви використовуєте db-запити, оскільки вони виконуються для кожного включеного підподання, компонента тощо, щоб ви могли закінчити сотні непотрібних запитів, найкраще використовувати базовий вид, наприклад, макети. додаток потім передає дані за необхідності.
Енді Лобель

Відповіді:


222

Цю ціль можна досягти різним методом,

1. Використання BaseController

Як я люблю налаштовувати речі, я BaseControllerскладаю клас, який розширює власний Laravel Controller, і встановлюю там різні глобальні речі. Всі інші контролери потім BaseControllerпоходять від контролера Laravel, а не від контролера Laravel.

class BaseController extends Controller
{
  public function __construct()
  {
    //its just a dummy data object.
    $user = User::all();

    // Sharing is caring
    View::share('user', $user);
  }
}

2. Використання фільтра

Якщо вам відомо, що ви хочете щось налаштувати для перегляду кожного запиту у всій програмі, ви також можете це зробити через фільтр, який працює до запиту - ось як я маю справу з об'єктом користувача в Laravel.

App::before(function($request)
{
  // Set up global user object for views
  View::share('user', User::all());
});

АБО

Ви можете визначити власний фільтр

Route::filter('user-filter', function() {
    View::share('user', User::all());
});

і викликати його за допомогою простого виклику фільтра.

Оновлення відповідно до версії 5. *

3. Використання середнього програмного забезпечення

Використання View::shareсmiddleware

Route::group(['middleware' => 'SomeMiddleware'], function(){
  // routes
});



class SomeMiddleware {
  public function handle($request)
  {
    \View::share('user', auth()->user());
  }
}

4. Використання View Composer

Перегляд композитора також допомагає пов'язувати конкретні дані для перегляду різними способами. Ви можете безпосередньо прив’язувати змінну до певного перегляду або до всіх представлень даних. Наприклад, ви можете створити власний каталог, щоб зберігати файл композитора перегляду відповідно до вимог. і ці файли композитора перегляду через Сервіс забезпечують взаємодію з представленням.

Переглянути композиторський метод можна по-різному. Перший приклад може виглядати однаково:

Ви можете створити App\Http\ViewComposersкаталог.

Постачальник послуг

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
    public function boot() {
        view()->composer("ViewName","App\Http\ViewComposers\TestViewComposer");
    }
}

Після цього додайте цього постачальника до config / app.php у розділі "провайдери".

TestViewComposer

namespace App\Http\ViewComposers;

use Illuminate\Contracts\View\View;

class TestViewComposer {

    public function compose(View $view) {
        $view->with('ViewComposerTestVariable', "Calling with View Composer Provider");
    }
}

ViewName.blade.php

Here you are... {{$ViewComposerTestVariable}}

Цей метод може допомогти лише для певного перегляду. Але якщо ви хочете запустити ViewComposer для всіх переглядів, ми повинні застосувати цю єдину зміну до ServiceProvider.

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
    public function boot() {
        view()->composer('*',"App\Http\ViewComposers\TestViewComposer");
    }
}

Довідково

Документація Laravel

Для подальшого уточнення епізоду Laracast

Якщо з моєї сторони все-таки щось незрозуміле, дайте мені знати.


У вашому прикладі відсутній register()метод - це необов'язково
Джонатан

@jonathan завдяки цьому, але приклад містить лише ті розділи, про які потрібно подбати. перспектива для обміну даними з переглядом.
Safoor Safdar

куди ти ставиш фільтр? Мабуть, найбільш правильною відповіддю є використання груп проміжних програм laravel.com/docs/5.3/middleware#middleware-groups або глобального середнього програмного забезпечення
Toskan

7
Це не дуже гарна ідея. Переглядайте композиторів, створюючи екземпляр композитора для кожного окремого перегляду, це означає, що якщо ви запускаєте цикл 1000 разів, буде створено 1000 екземплярів композитора, і 1000 разів обробляється подія стрільби, що не те, чого ви хочете.
Реза Шадман

4
@RezaShadman вірно! Я навчився цього важким шляхом. Моя програма працювала так повільно, поки я не встановив інструмент для відлагодження laravel для дослідження. Тоді я зрозумів, що всі 8 запитів, де виконуються близько 15 разів для одного завантаження сторінки. Це відбувається тому, що композитор перегляду буде викликаний для кожного файлу леза, що входить. Тобто, якщо ви використовуєте зірочку *. Якщо ви не користуєтесь, *то вам слід добре.
Сиклон

66

Ви можете створити власного постачальника послуг ( ViewServiceProviderім'я є загальним) або використовувати існуючого AppServiceProvider.

У вибраному провайдері введіть свій код у метод завантаження.

public function boot() {
    view()->share('data', [1, 2, 3]);
}

Це зробить $dataзмінну доступною для всіх ваших переглядів.

Якщо ви хочете скористатися фасадом замість помічника, перейдіть view()->на, View::але не забудьте мати його use View;у верхній частині файлу.


Дякую, чудово працюю. Чи призначена функція завантаження для подібних речей чи ви рекомендуєте створити власного постачальника послуг?
Рагнарссон

2
Якщо у вас є лише одна або дві речі, щоб поділитися ними, AppServiceProviderце добре, але якщо у вас є щось більше, ви можете розглянути можливість створення нового постачальника.
Марвеллн

Це працювало, але я просто бачу, що його не працює сьогодні! використання composer updateтакож не працює. Насправді це зовсім не стрілянина boot(). Мені потрібно поділитися двома змінними.
itsazzad

11
Майте на увазі, що це не спрацює, якщо ви отримуєте записи баз даних, оскільки це буде викликано перед виконанням міграцій. Таким чином, ви в основному намагаєтеся отримати записи баз даних, перш ніж вони існують. Принаймні, так мені здається.
lorey

1
На жаль, це, мабуть, не працює з діленням авторизованого користувача Auth :: user (), відповідь №1 Safoor, нижче цього, робить :)
Stan Smulders

11

Я вважав це найпростішим. Створіть нового постачальника та користувачу '*'підстановку, щоб додати його до всіх переглядів. Також працює в 5.3 :-)

<?php

namespace App\Providers;

use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;

class ViewServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     * @return void
     */
    public function boot()
    {
        view()->composer('*', function ($view)
        {
            $user = request()->user();

            $view->with('user', $user);
        });
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

2
Додайте цього постачальника до масиву провайдерів у вашому конфігурації / програмі "App \ Providers \ ViewServiceProvider :: class",
Nadeem0035

8

Найкращим способом було б спільне використання змінної за допомогою View::share('var', $value);

Проблеми зі складанням за допомогою "*":

Розглянемо наступний підхід:

<?php
// from AppServiceProvider::boot()
$viewFactory = $this->app->make(Factory::class);

$viewFacrory->compose('*', GlobalComposer::class);

З прикладу перегляду леза:

  @for($i = 0; $i<1000; $i++)
    @include('some_partial_view_to_display_i', ['toDisplay' => $i])
  @endfor

Що станеться?

  • GlobalComposerКлас інстанцііруется 1000 раз з використанням App::make .
  • Подія composing:some_partial_view_to_display_iпроводиться 1000 разів.
  • composeФункція всередині GlobalComposerкласу називається 1000 разів.

Але частковий вигляд some_partial_view_to_display_iне має нічого спільного з змінними, складенимиGlobalComposer але сильно збільшує час візуалізації.

Кращий підхід?

Використання View::shareзгрупованих проміжних програм.

Route::group(['middleware' => 'WebMiddleware'], function(){
  // Web routes
});

Route::group(['prefix' => 'api'], function (){

});

class WebMiddleware {
  public function handle($request)
  {
    \View::share('user', auth()->user());
  }
}

Оновлення

Якщо ви використовуєте щось, що обчислюється через конвеєр програмного забезпечення, ви можете просто прослухати належну подію або поставити проміжне програмне забезпечення перегляду в останню частину конвеєра.


4

У документації:

Як правило, ви б здійснювали дзвінки до методу загального користування у методі завантаження постачальника послуг. Ви можете додати їх до AppServiceProvider або створити окремого постачальника послуг, щоб розмістити їх.

Я погоджуюся з Marwelln, просто поставте його AppServiceProviderу функцію завантаження:

public function boot() {
    View::share('youVarName', [1, 2, 3]);
}

Я рекомендую використовувати конкретну назву змінної, щоб уникнути плутанини або помилок з іншими, не "глобальними" змінними.


3

Документація прослуховується https://laravel.com/docs/5.4/views#view-composers, але я буду її розбивати

  1. Шукайте додаток каталогів \ Провайдери у кореневому каталозі вашої програми та створіть файл ComposerServiceProvider.php та скопіюйте та вставте текст нижче в нього та збережіть його.

    <?php
        namespace App\Providers;
        use Illuminate\Support\Facades\View;
        use Illuminate\Support\ServiceProvider;
    
        class ComposerServiceProvider extends ServiceProvider
        {
            /**
            * Register bindings in the container.
            *
            * @return void
            */
        public function boot()
        {
            // Using class based composers...
            View::composer(
                'profile', 'App\Http\ViewComposers\ProfileComposer'
            );
    
            // Using Closure based composers...
            View::composer('dashboard', function ($view) {
                //
            });
        }
    
        /**
        * Register the service provider.
        *
        * @return void
        */
        public function register()
        {
            //
        }
    }
  2. Від кореня програми відкрийте Config / app.php і знайдіть розділ Постачальники у файлі та скопіюйте та пройдіть цей масив у програму "App \ Providers \ ComposerServiceProvider" .

Цим ми створили постачальника послуг композитора. Коли ви запускаєте свою програму з таким профілем перегляду, як http: // yourdomain / something / profile , викликається постачальник послуг ComposerServiceProvider і клас App \ Http \ ViewComposers \ ProfileComposer миттєво викликає метод Composer завдяки коду нижче всередині метод або функція завантаження.

 // Using class based composers...
 View::composer(
   'profile', 'App\Http\ViewComposers\ProfileComposer'
 );
  1. Якщо ви оновите свою програму, ви отримаєте помилку, оскільки клас App \ Http \ ViewComposers \ ProfileComposer ще не існує. Тепер давайте створимо його.

Перейдіть у додаток шлях до каталогу / Http

  • Створіть каталог під назвою ViewComposers

  • Створіть файл ProfileComposer.php .

    class ProfileComposer
    {
        /**
        * The user repository implementation.
        *
        * @var UserRepository
        */
        protected $users;
    
        /**
        * Create a new profile composer.
        *
        * @param  UserRepository  $users
        * @return void
        */
        public function __construct(UserRepository $users)
        {
            // Dependencies automatically resolved by service container...
            $this->users = $users;
        }
    
        /**
        * Bind data to the view.
        *
        * @param  View  $view
        * @return void
        */
        public function compose(View $view)
        {
            $view->with('count', $this->users->count());
        }
    }

Тепер перейдіть до свого перегляду або в цьому випадку Profile.blade.php та додайте

{{ $count }}

і це покаже кількість користувачів на сторінці профілю.

Щоб показати кількість змін на всіх сторінках, змініть

// Using class based composers...
View::composer(
    'profile', 'App\Http\ViewComposers\ProfileComposer'
);

До

// Using class based composers...
View::composer(
    '*', 'App\Http\ViewComposers\ProfileComposer'
);

<? php та простір імен App \ Http \ ViewComposers; використовувати Illuminate \ Contracts \ View \ View; відсутня у
ProfileComposer.php



1

Всередині папки конфігурації ви можете створити ім'я файлу php, наприклад, "varia.php" із вмістом нижче:

<?php

  return [
    'versionNumber' => '122231',
  ];

Тепер усередині переглядів ви можете ним користуватися

config('variable.versionNumber')

Я роблю це таким чином у деяких випадках, оскільки інформація справді глобальна, і ви можете отримати доступ до неї з будь-якого місця. З цієї причини я називаю конфігураційний файл "global.php" і вкладаю все, що мені хочеться бути доступним у всіх інших частинах коду. Єдине обмеження полягає в тому, що це стосується статичних даних і отримує кешування. Його не слід використовувати таким чином, якщо у вас постійно змінюються дані.
eResourcesInc

1

1) В (додаток \ Постачальники \ AppServiceProvider.php)

// in boot function
       view()->composer('*', function ($view) {
            $data = User::messages();
            $view->with('var_messages',$data);
        });

2) у Вашій моделі користувача

  public static function messages(){ // this is just example
        $my_id = auth()->user()->id;
        $data= Message::whereTo($my_id)->whereIs_read('0')->get(); 
        return $data; // return is required
    }

3) у Вашому перегляді

 {{ $var_messages }}

0

Метод Laravel 5.6: https://laravel.com/docs/5.6/views#passing-data-to-views

Наприклад, з набором колекції моделей для всіх представлень даних (AppServiceProvider.php):

use Illuminate\Support\Facades\View;
use App\Product;

public function boot()
{
    $products = Product::all();
    View::share('products', $products);

}

2
Це спричинить проблеми, якщо ви намагаєтесь створити свіжий додаток із порожньою базою даних.
Кріс Герберт

0

У вас є два варіанти:

1.Поділитися за допомогою функції завантаження в App \ Providers \ AppServiceProvider

public function boot() { view()->share('key', 'value'); }

І отримати доступ до змінної $ key у будь-якому файлі перегляду.

Примітка. Пам’ятайте, що ви не можете отримати доступ до поточних даних сеансів, аутентифікації, маршруту тут. Цей варіант хороший лише в тому випадку, якщо ви хочете ділитися статичними даними. Припустимо, ви хочете поділитися деякими даними на основі поточного користувача, маршруту чи будь-якої спеціальної змінної сеансу, ви не зможете цього зробити.

  1. Використання класів помічників Створіть клас помічників у будь-якій точці вашої програми та зареєструйте його у масиві Alias ​​у файлі app.php у папці config.

'aliases' => [ ..., 'Helper' => App\HelperClass\Helper::class, ],

і створіть Helper.php у папці HelperClass у папці програми

namespace App\HelperClass;

class Helper
{
    public static function Sample()
    {
        //Your Code Here
    }
}

і отримувати доступ до нього будь-де Helper::Sample()

Тут ви не будете обмежені для використання Auth, Route, Session або будь-яких інших класів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.