Come passare i dati a tutte le visualizzazioni in Laravel 5?


125

Voglio avere alcuni dati predefiniti accessibili in tutte le visualizzazioni nella mia applicazione Laravel 5.

Ho provato a cercarlo, ma ho trovato solo risultati per Laravel 4. Ho letto la documentazione "Condivisione dei dati con tutte le viste" qui ma non riesco a capire cosa fare. Dove dovrebbe essere posizionato il codice seguente?

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

Grazie per l'aiuto.


bene, hai bisogno del codice di avvio per gestire questo requisito?
Safoor Safdar

1
avvisa utilizzando View :: share in un provider di servizi con i risultati di una chiamata al database, l'applicazione verrà visualizzata in errore quando si esegue una migrazione di aggiornamento del database o si tenta di eseguire il crepuscolo con una connessione db non raggiungibile (storia lunga, .env.dusk.local è utilizzato solo dopo l'esecuzione del provider di servizi). Come accennato di seguito in un controller di base o un middlware è il migliore.
Andy Lobel

Fai anche attenzione quando usi i *compositori sulla vista, specialmente se usi le query db, poiché viene eseguito per ogni vista secondaria inclusa, componente, ecc., Quindi potresti finire per eseguire centinaia di query non necessarie, la cosa migliore è usare la vista di base, ad esempio i layout. quindi passare i dati in base alle esigenze.
Andy Lobel

Risposte:


222

Questo obiettivo può essere raggiunto con metodi diversi,

1. Utilizzo di BaseController

Per come mi piace impostare le cose, BaseControllercreo una classe che estenda quella di Laravel Controllere lì organizzo varie cose globali. Tutti gli altri controller si estendono quindi da BaseControllerpiuttosto che dal controller di 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. Utilizzo del filtro

Se sai per certo che vuoi qualcosa configurato per le visualizzazioni su ogni richiesta nell'intera applicazione, puoi anche farlo tramite un filtro che viene eseguito prima della richiesta: è così che gestisco l'oggetto Utente in Laravel.

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

O

Puoi definire il tuo filtro

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

e chiamalo tramite una semplice chiamata di filtro.

Aggiorna in base alla versione 5. *

3. Utilizzo del middleware

Utilizzando il View::shareconmiddleware

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



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

4. Utilizzo di View Composer

View Composer aiuta anche a legare dati specifici per la visualizzazione in modi diversi. È possibile associare direttamente la variabile a una visualizzazione specifica oa tutte le visualizzazioni. Ad esempio è possibile creare la propria directory per memorizzare il file del compositore di visualizzazione in base alle esigenze. e questi file del compositore di visualizzazione tramite il servizio forniscono interagiscono con la visualizzazione.

Il metodo di composizione della vista può essere utilizzato in modo diverso, il primo esempio può essere simile:

Potresti creare una App\Http\ViewComposersdirectory.

Fornitore di servizi

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

Dopodiché, aggiungi questo provider a config / app.php nella sezione "provider".

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

Questo metodo potrebbe essere utile solo per View specifici. Ma se vuoi attivare ViewComposer su tutte le viste, dobbiamo applicare questa singola modifica a ServiceProvider.

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

Riferimento

Documentazione Laravel

Per ulteriori chiarimenti Episodio Laracast

Se c'è ancora qualcosa di poco chiaro da parte mia, fammi sapere.


Nel tuo esempio manca il register()metodo - non è opzionale
Jonathan

@jonathan grazie per segnalarlo, ma l'esempio contiene solo quelle sezioni di cui occuparsi. prospettiva di condivisione dei dati con vista.
Safoor Safdar

dove metti il ​​filtro? probabilmente la risposta più corretta sta ora utilizzando i gruppi middleware laravel.com/docs/5.3/middleware#middleware-groups o middleware globale
Toskan

7
Questa non è una buona idea, i compositori della vista creano l'istanza del compositore per ogni singola vista significa che se esegui un ciclo di 1000 volte, verranno create 1000 istanze del compositore e, 1000 volte viene gestito l'evento di attivazione che non è qualcosa che desideri.
Reza Shadman

4
@RezaShadman ha ragione! L'ho imparato nel modo più duro. La mia applicazione funzionava così lentamente finché non ho installato lo strumento laravel-debugbar per indagare. Poi ho capito che tutte le 8 query venivano eseguite circa 15 volte per un caricamento di una singola pagina. Questo perché il compositore di viste verrà chiamato per ogni file blade incluso. Cioè se stai usando l'asterisco *. Se non stai usando *allora dovresti stare bene.
Syclone

66

Puoi creare il tuo fornitore di servizi (il ViewServiceProvidernome è comune) oppure puoi utilizzare il file AppServiceProvider.

Nel provider selezionato, inserisci il codice nel metodo di avvio.

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

Ciò renderà una $datavariabile accessibile in tutte le tue visualizzazioni.

Se preferisci usare la facciata invece dell'helper, cambia view()->in View::ma non dimenticare di avere use View;all'inizio del tuo file.


Grazie, funziona benissimo. La funzione di avvio è pensata per questo genere di cose o mi consigliate di creare il mio fornitore di servizi?
Ragnarsson

2
Se hai solo una o due cose da condividere, inserirle AppServiceProviderva bene, ma se hai qualcosa di più dovresti considerare la creazione di un nuovo provider.
Marwelln

Funzionava ma vedo solo che oggi non funziona! utilizzando composer updateanche non funziona. In realtà non sta sparando boot()affatto. Ho bisogno di condividere due variabili.
itsazzad

11
Tieni presente che questo non funzionerà se stai recuperando i record del database poiché verrà chiamato prima di eseguire le migrazioni. Quindi stai fondamentalmente cercando di recuperare i record del database prima che esistano. Almeno questo sembra essere il caso per me.
lorey

1
Sfortunatamente questo non sembra funzionare con la condivisione di un utente connesso Auth :: user (), la risposta n. 1 di Safoor, sotto questa, funziona :)
Stan Smulders

11

Ho trovato questo il più semplice. Crea un nuovo provider e utilizza il '*'carattere jolly per allegarlo a tutte le viste. Funziona anche 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()
    {
        //
    }
}

2
Aggiungi questo provider all'array di provider nella tua configurazione / app "App \ Providers \ ViewServiceProvider :: class,"
Nadeem0035

8

Il modo migliore sarebbe condividere la variabile utilizzando View::share('var', $value);

Problemi con la composizione utilizzando "*":

Considera il seguente approccio:

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

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

Da una vista blade di esempio:

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

Che succede?

  • La GlobalComposerclasse viene istanziata 1000 volte utilizzando App::make.
  • L'evento composing:some_partial_view_to_display_iviene gestito 1000 volte.
  • La composefunzione all'interno della GlobalComposerclasse viene chiamata 1000 volte.

Ma la vista parziale some_partial_view_to_display_inon ha nulla a che fare con le variabili composte da GlobalComposerma aumenta notevolmente il tempo di rendering.

Miglior approccio?

Utilizzo View::sharelungo un middleware raggruppato.

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

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

});

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

Aggiornare

Se stai usando qualcosa che viene calcolato tramite la pipeline del middleware, puoi semplicemente ascoltare l' evento corretto o mettere il middleware della condivisione della vista nell'ultima parte inferiore della pipeline.


4

Nella documentazione:

In genere, si effettuano chiamate al metodo di condivisione all'interno del metodo di avvio di un provider di servizi. Sei libero di aggiungerli ad AppServiceProvider o di generare un provider di servizi separato per ospitarli.

Sono d'accordo con Marwelln, inseriscilo nella AppServiceProviderfunzione di avvio:

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

Consiglio di utilizzare un nome specifico per la variabile, per evitare confussioni o errori con altre variabili non "globali".


3

La documentazione è ascoltata https://laravel.com/docs/5.4/views#view-composers ma la analizzerò

  1. Cerca la directory app \ Providers nella directory principale della tua applicazione e crea il file ComposerServiceProvider.php, copia e incolla il testo qui sotto e salvalo.

    <?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. Dalla radice della tua applicazione apri Config / app.php e cerca la sezione Provider nel file e copia e incolla questo "App \ Providers \ ComposerServiceProvider", nell'array.

In questo modo, abbiamo creato il Composer Service Provider. Quando esegui la tua applicazione con la vista Profile in questo modo http: // yourdomain / something / profile , viene chiamato il provider di servizi ComposerServiceProvider e viene istanziata la classe App \ Http \ ViewComposers \ ProfileComposer chiamando il metodo Composer a causa del codice sottostante all'interno del metodo o funzione di avvio.

 // Using class based composers...
 View::composer(
   'profile', 'App\Http\ViewComposers\ProfileComposer'
 );
  1. Se aggiorni la tua applicazione riceverai un errore perché la classe App \ Http \ ViewComposers \ ProfileComposer non esiste ancora. Ora creiamolo.

Vai al percorso della directory app / Http

  • Crea la directory chiamata ViewComposers

  • Crea il file 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());
        }
    }

Ora vai alla tua vista o in questo caso Profile.blade.php e aggiungi

{{ $count }}

e questo mostrerà il conteggio degli utenti nella pagina del profilo.

Per mostrare il conteggio su tutte le pagine cambia

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

Per

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

<? php e spazio dei nomi App \ Http \ ViewComposers; utilizzare Illumina \ Contratti \ Visualizza \ Visualizza; manca in ProfileComposer.php
Unicco



1

All'interno della tua cartella di configurazione puoi creare un file php chiamandolo ad esempio "variabile.php" con il contenuto di seguito:

<?php

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

Ora all'interno di tutte le visualizzazioni puoi usarlo come

config('variable.versionNumber')

In alcuni casi lo faccio in questo modo, perché le informazioni sono veramente globali e puoi accedervi da qualsiasi luogo. Per questo motivo, chiamo il file di configurazione "global.php" e inserisco tutto ciò che voglio sia accessibile in tutte le altre parti del mio codice. L'unica limitazione è che questo è per i dati statici e viene memorizzato nella cache. Non dovrebbe essere usato in questo modo se hai dati in continua evoluzione.
eResourcesInc

1

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

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

2) nel tuo modello utente

  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) in Your View

 {{ $var_messages }}

0

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

Esempio, con la condivisione di una raccolta di modelli su tutte le viste (AppServiceProvider.php):

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

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

}

2
Ciò causerà problemi se stai cercando di creare una nuova applicazione con un database vuoto.
Chris Herbert

0

Hai due opzioni:

1.Condividere tramite la funzione di avvio in App \ Providers \ AppServiceProvider

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

E accedi alla variabile $ key in qualsiasi file di visualizzazione.

Nota: ricorda che non puoi accedere ai dati di Sessione, Autenticazione e Rotta correnti qui. Questa opzione è utile solo se desideri condividere dati statici. Supponi di voler condividere alcuni dati in base all'utente corrente, al percorso o a qualsiasi variabile di sessione personalizzata che non sarai in grado di fare con questo.

  1. Uso di una classe helper Crea una classe helper ovunque nella tua applicazione e registrala nell'array Alias ​​nel file app.php nella cartella config.

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

e crea Helper.php nella cartella HelperClass all'interno della cartella App

namespace App\HelperClass;

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

e accedervi ovunque come Helper::Sample()

Non sarai limitato qui per utilizzare Auth, Route, Session o qualsiasi altra classe.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.