Wie übergebe ich Daten an alle Ansichten in Laravel 5?

125

Ich möchte, dass einige Standarddaten in allen Ansichten meiner Laravel 5-Anwendung verfügbar sind.

Ich habe versucht, danach zu suchen, aber nur Ergebnisse für Laravel 4 gefunden. Ich habe die Dokumentation "Daten mit allen Ansichten teilen " hier gelesen , kann aber nicht verstehen, was zu tun ist. Wo soll der folgende Code platziert werden?

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

Danke für Ihre Hilfe.

Ragnarsson
quelle
Nun, Sie benötigen Startcode, um diese Anforderung zu verwalten?
Safoor Safdar
1
Wenn Sie View :: share in einem Dienstanbieter mit den Ergebnissen eines Datenbankaufrufs verwenden, wird die Anwendung beim Ausführen einer Aktualisierung der Datenbankmigration oder beim Versuch, die Dämmerung mit einer nicht erreichbaren Datenbankverbindung auszuführen, fehlerhaft (lange Geschichte, .env.dusk.local ist wird nur verwendet, nachdem der Dienstanbieter ausgeführt wurde). Wie unten erwähnt, ist ein Basis-Controller oder eine mittlere Software die beste.
Andy Lobel
Seien Sie auch vorsichtig, wenn Sie *On-View-Composer verwenden, insbesondere wenn Sie DB-Abfragen verwenden, da diese für jede enthaltene Unteransicht, Komponente usw. ausgeführt werden, sodass Sie möglicherweise Hunderte unnötiger Abfragen ausführen. Verwenden Sie am besten die Basisansicht, z. B. Layouts. App dann Daten nach Bedarf weitergeben.
Andy Lobel

Antworten:

220

Dieses Ziel kann durch verschiedene Methoden erreicht werden,

1. Verwenden von BaseController

So wie ich Dinge gerne einrichte, mache ich eine BaseControllerKlasse, die Laravels eigene erweitert Controller, und richte dort verschiedene globale Dinge ein. Alle anderen Controller erstrecken sich dann von BaseControllerLaravels Controller.

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

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

2. Filter verwenden

Wenn Sie wissen, dass für jede Anforderung in der gesamten Anwendung etwas für Ansichten eingerichtet werden soll, können Sie dies auch über einen Filter tun, der vor der Anforderung ausgeführt wird. So gehe ich mit dem Benutzerobjekt in Laravel um.

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

ODER

Sie können Ihren eigenen Filter definieren

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

und rufen Sie es durch einfachen Filteraufruf auf.

Update gemäß Version 5. *

3. Middleware verwenden

Mit dem View::sharemitmiddleware

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



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

4. Verwenden von View Composer

View Composer hilft auch dabei, bestimmte Daten zu binden, um sie auf unterschiedliche Weise anzuzeigen. Sie können Variablen direkt an eine bestimmte Ansicht oder an alle Ansichten binden. Zum Beispiel können Sie ein eigenes Verzeichnis erstellen, um Ihre View Composer-Datei je nach Anforderung zu speichern. und diese View Composer-Datei über Service bieten Interaktion mit der Ansicht.

Die View Composer-Methode kann auf unterschiedliche Weise verwendet werden. Das erste Beispiel kann ähnlich aussehen:

Sie könnten ein App\Http\ViewComposersVerzeichnis erstellen .

Dienstleister

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

Fügen Sie danach diesen Anbieter zu config / app.php im Abschnitt "Anbieter" hinzu.

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}}

Diese Methode kann nur für bestimmte Ansichten hilfreich sein. Wenn Sie jedoch ViewComposer für alle Ansichten auslösen möchten, müssen Sie diese einzelne Änderung auf ServiceProvider anwenden.

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

Referenz

Laravel-Dokumentation

Zur weiteren Klärung Laracast Episode

Wenn mir noch etwas unklar ist, lass es mich wissen.

Safoor Safdar
quelle
In Ihrem Beispiel fehlt die register()Methode - sie ist nicht optional
Jonathan
@ Jonathan danke, um darauf hinzuweisen, aber Beispiel enthält nur die Abschnitte, um die man sich kümmern muss. Perspektive zum Teilen von Daten mit Ansicht.
Safoor Safdar
Wo setzen Sie den Filter ein? Die wahrscheinlich richtigste Antwort ist jetzt die Verwendung von Middleware-Gruppen laravel.com/docs/5.3/middleware#middleware-groups oder globaler Middleware
Toskan
7
Dies ist keine gute Idee. View Composers erstellen die Composer-Instanz für jede einzelne Ansicht. Wenn Sie eine 1000-fache Schleife ausführen, werden 1000 Composer-Instanzen erstellt und das 1000-fache des Auslöseereignisses wird behandelt, was Sie nicht möchten.
Reza Shadman
4
@RezaShadman ist richtig! Ich habe das auf die harte Tour gelernt. Meine Anwendung lief so langsam, bis ich das Laravel-Debugbar-Tool zur Untersuchung installierte. Dann wurde mir klar, dass alle 8 Abfragen ungefähr 15 Mal für das Laden einer einzelnen Seite ausgeführt wurden. Dies liegt daran, dass der View Composer für jede enthaltene Blade-Datei aufgerufen wird. Das ist, wenn Sie das Sternchen verwenden *. Wenn Sie das nicht verwenden *, sollte es Ihnen gut gehen.
Syclone
66

Sie können entweder Ihren eigenen Dienstanbieter erstellen (ViewServiceProvider Name ist üblich) oder den vorhandenen verwenden AppServiceProvider.

Geben Sie in Ihrem ausgewählten Anbieter Ihren Code in die Startmethode ein.

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

Dies wird eine machen $data Variable in all Ihren Ansichten zugänglich.

Wenn Sie lieber die Fassade als den Helfer verwenden möchten, wechseln Sie view()->zu, View::aber vergessen Sie nicht, sie use View;oben in Ihrer Datei zu haben.

Marwelln
quelle
Danke, es funktioniert großartig. Ist die Boot-Funktion für solche Dinge gedacht oder empfehlen Sie, einen eigenen Dienstanbieter zu erstellen?
Ragnarsson
2
Wenn Sie nur ein oder zwei Dinge zum Teilen haben, ist es in AppServiceProviderOrdnung, aber wenn Sie mehr als das haben, sollten Sie in Betracht ziehen, einen neuen Anbieter zu erstellen.
Marwelln
Es hat funktioniert, aber ich sehe nur, dass es heute nicht funktioniert! mit composer updateauch nicht funktioniert. Eigentlich feuert es das boot()überhaupt nicht ab. Ich muss zwei Variablen teilen.
Itsazzad
11
Beachten Sie, dass dies nicht funktioniert, wenn Sie Datenbankeinträge abrufen, da diese vor dem Ausführen von Migrationen aufgerufen werden. Sie versuchen also im Grunde, Datenbankeinträge abzurufen, bevor sie existieren. Zumindest scheint das bei mir der Fall zu sein.
Lorey
1
Leider scheint dies nicht mit der Freigabe eines angemeldeten Benutzers Auth :: user () zu funktionieren, Safoors Antwort Nr. 1 unter dieser :)
Stan Smulders
11

Ich fand das am einfachsten. Erstellen Sie einen neuen Anbieter und verwenden Sie den '*'Platzhalter, um ihn an alle Ansichten anzuhängen. Funktioniert auch in 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()
    {
        //
    }
}
Stan Smulders
quelle
2
Fügen Sie diesen Anbieter zu einer Reihe von Anbietern in Ihrer Konfiguration / App "App \ Providers \ ViewServiceProvider :: class" hinzu
Nadeem0035
8

Der beste Weg wäre, die Variable mit zu teilen View::share('var', $value);

Probleme beim Komponieren mit "*":

Betrachten Sie folgenden Ansatz:

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

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

Aus einer beispielhaften Blade-Ansicht:

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

Was geschieht?

  • Die GlobalComposerKlasse wird 1000- mal mit instanziiert App::make.
  • Das Ereignis composing:some_partial_view_to_display_iwird 1000 Mal behandelt.
  • Die composeFunktion innerhalb der GlobalComposerKlasse wird 1000 Mal aufgerufen.

Die Teilansicht some_partial_view_to_display_ihat jedoch nichts mit den Variablen zu tun, die aus der Renderzeit bestehen, GlobalComposersondern erhöht diese stark.

Bester Ansatz?

Verwendung View::shareentlang einer gruppierten Middleware.

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

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

});

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

Aktualisieren

Wenn Sie etwas verwenden, das über die Middleware-Pipeline berechnet wird, können Sie einfach das richtige Ereignis abhören oder die View-Share-Middleware am letzten Ende der Pipeline platzieren.

Reza Shadman
quelle
4

In der Dokumentation:

In der Regel rufen Sie die Freigabemethode innerhalb der Startmethode eines Dienstanbieters auf. Sie können sie dem AppServiceProvider hinzufügen oder einen separaten Dienstanbieter generieren, um sie unterzubringen.

Ich bin mit Marwelln einverstanden, füge es einfach AppServiceProviderin die Boot-Funktion ein:

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

Ich empfehle, einen bestimmten Namen für die Variable zu verwenden, um Verwechslungen oder Fehler mit anderen nicht 'globalen' Variablen zu vermeiden.

Santiago Mendoza Ramirez
quelle
3

Die Dokumentation ist unter https://laravel.com/docs/5.4/views#view-composers zu hören, aber ich werde sie aufschlüsseln

  1. Suchen Sie im Stammverzeichnis Ihrer Anwendung nach dem Verzeichnis app \ Providers, erstellen Sie die Datei ComposerServiceProvider.php, kopieren Sie den folgenden Text, fügen Sie ihn ein und speichern Sie ihn.

    <?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. Öffnen Sie im Stammverzeichnis Ihrer Anwendung Config / app.php und suchen Sie in der Datei nach dem Abschnitt Providers. Kopieren Sie diesen 'App \ Providers \ ComposerServiceProvider' und fügen Sie ihn in das Array ein.

Auf diese Weise haben wir den Composer Service Provider erstellt. Wenn Sie Ihre Anwendung mit dem Ansichtsprofil wie http: // IhreDomäne / etwas / Profil ausführen , wird der Dienstanbieter ComposerServiceProvider aufgerufen und die Klasse App \ Http \ ViewComposers \ ProfileComposer wird instanziiert, indem die Methode Composer aufgrund des folgenden Codes in der aufgerufen wird Boot-Methode oder -Funktion.

 // Using class based composers...
 View::composer(
   'profile', 'App\Http\ViewComposers\ProfileComposer'
 );
  1. Wenn Sie Ihre Anwendung aktualisieren, wird eine Fehlermeldung angezeigt, da die Klasse App \ Http \ ViewComposers \ ProfileComposer noch nicht vorhanden ist. Jetzt erstellen wir es.

Gehen Sie zum Verzeichnispfad app / Http

  • Erstellen Sie das Verzeichnis ViewComposers

  • Erstellen Sie die Datei 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());
        }
    }

Gehen Sie nun zu Ihrer Ansicht oder in diesem Fall zu Profile.blade.php und fügen Sie hinzu

{{ $count }}

und das zeigt die Anzahl der Benutzer auf der Profilseite.

Um die Anzahl auf allen Seiten anzuzeigen, ändern Sie sich

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

Zu

// Using class based composers...
View::composer(
    '*', 'App\Http\ViewComposers\ProfileComposer'
);
Samuel Kwame Antwi
quelle
<? php und Namespace App \ Http \ ViewComposers; Verwenden Sie Illuminate \ Contracts \ View \ View. fehlt in
ProfileComposer.php
1

Ich denke, dass der beste Weg mit ist View Composers. Wenn jemand hierher gekommen ist und herausfinden möchte, wie dies mit View Composers möglich ist, lesen Sie meine Antwort => Wie kann ich eine Variable für alle Ansichten freigeben ?

Panagiotis Koursaris
quelle
1

Die Dokumentation finden Sie hier https://laravel.com/docs/5.4/views#view-composers, aber ich werde sie aufschlüsseln. 1. Suchen Sie in Ihrem Stammverzeichnis nach den Verzeichnisanbietern und erstellen Sie die für ComposerServiceProvider.php mit Inhalt

Samuel Kwame Antwi
quelle
1

In Ihrem Konfigurationsordner können Sie einen PHP-Dateinamen erstellen, zum Beispiel "variable.php" mit dem folgenden Inhalt:

<?php

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

Jetzt können Sie es in allen Ansichten wie verwenden

config('variable.versionNumber')
Mehran
quelle
In einigen Fällen mache ich das so, weil die Informationen wirklich global sind und Sie von überall darauf zugreifen können. Aus diesem Grund rufe ich die Konfigurationsdatei "global.php" auf und füge dort alles ein, auf das ich in allen anderen Teilen meines Codes zugreifen möchte. Die einzige Einschränkung besteht darin, dass dies für statische Daten gilt und zwischengespeichert wird. Es sollte nicht auf diese Weise verwendet werden, wenn sich die Daten ständig ändern.
eResourcesInc
1

1) In (app \ Providers \ AppServiceProvider.php)

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

2) in Ihrem Benutzermodell

  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) aus Ihrer Sicht

 {{ $var_messages }}
Abdelhakim Ezzahraoui
quelle
0

Laravel 5.6 Methode: https://laravel.com/docs/5.6/views#passing-data-to-views

Beispiel für die Freigabe einer Modellsammlung für alle Ansichten (AppServiceProvider.php):

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

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

}
Alexander Kim
quelle
2
Dies führt zu Problemen, wenn Sie versuchen, eine neue Anwendung mit einer leeren Datenbank zu erstellen.
Chris Herbert
0

Sie haben zwei Möglichkeiten:

1. Teilen Sie über die Boot-Funktion in App \ Providers \ AppServiceProvider

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

Und greifen Sie in jeder Ansichtsdatei auf die Variable $ key zu.

Hinweis: Beachten Sie, dass Sie hier nicht auf aktuelle Sitzungs-, Authentifizierungs- und Routendaten zugreifen können. Diese Option ist nur dann sinnvoll, wenn Sie statische Daten freigeben möchten. Angenommen, Sie möchten einige Daten basierend auf dem aktuellen Benutzer, der Route oder einer benutzerdefinierten Sitzungsvariablen freigeben, die Sie damit nicht ausführen können.

  1. Verwendung einer Hilfsklasse Erstellen Sie eine Hilfsklasse an einer beliebigen Stelle in Ihrer Anwendung und registrieren Sie sie im Alias-Array in der Datei app.php im Konfigurationsordner.

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

und erstellen Sie Helper.php im HelperClass-Ordner im App-Ordner

namespace App\HelperClass;

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

und überall darauf zugreifen Helper::Sample()

Sie sind hier nicht darauf beschränkt, Auth, Route, Session oder andere Klassen zu verwenden.

Priya Chetwani
quelle