Laravel 5'teki tüm görünümlere veri nasıl aktarılır?


125

Laravel 5 uygulamamdaki tüm görünümlerde bazı varsayılan verilere erişilebilmesini istiyorum.

Onu aramaya çalıştım ama sadece Laravel 4 için sonuçlar buldum. Burada 'Verileri Tüm Görünümlerle Paylaşma' belgesini okudum ama ne yapacağımı anlayamıyorum. Aşağıdaki kod nereye yerleştirilmelidir?

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

Yardımınız için teşekkürler.


Peki, bu gereksinimi yönetmek için başlangıç ​​koduna mı ihtiyacınız var?
Safoor Safdar

1
View :: share'i bir servis sağlayıcıda veritabanı çağrısının sonuçlarıyla birlikte kullanmak, bir yenileme db geçişi çalıştırırken veya ulaşılamaz bir db bağlantısıyla alacakaranlık çalıştırmaya çalışırken uygulamada hata verecektir (uzun hikaye, .env.dusk.local is yalnızca servis sağlayıcı çalıştırıldıktan sonra kullanılır). Aşağıda belirtildiği gibi, bir temel denetleyicide veya orta yazılımda en iyisidir.
Andy Lobel

Ayrıca *, görünüm oluşturucuları kullanırken özellikle db sorguları kullanıyorsanız dikkatli olun , çünkü dahil edilen her alt görünüm, bileşen vb. İçin çalıştırılır, böylece yüzlerce gereksiz sorgu çalıştırabilirsiniz, en iyisi temel görünümü kullanmaktır, örneğin düzenler. app daha sonra verileri gerektiği gibi aktarır.
Andy Lobel

Yanıtlar:


222

Bu hedefe farklı yöntemlerle ulaşılabilir,

1. BaseController'ı kullanma

İşleri kurmayı sevdiğim gibi, BaseControllerLaravel'in kendi sınıfını genişleten bir sınıf oluşturuyorum Controllerve orada çeşitli küresel şeyler kuruyorum . Diğer tüm denetleyiciler BaseControllerLaravel'in Denetleyicisinden ziyade genişler.

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

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

2. Filtre Kullanımı

Tüm uygulama boyunca her istek üzerine görünümler için ayarlanan bir şey istediğinizi biliyorsanız, bunu talepten önce çalışan bir filtre aracılığıyla da yapabilirsiniz - Laravel'de Kullanıcı nesnesiyle bu şekilde ilgileniyorum.

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

VEYA

Kendi filtrenizi tanımlayabilirsiniz

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

ve basit filtre çağrısı yoluyla çağırın.

Sürüm 5'e Göre Güncelleme *

3. Ara Yazılım Kullanma

Kullanımı View::shareilemiddleware

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



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

4. View Composer'ı Kullanma

View Composer, belirli verileri farklı şekillerde görüntülemek için bağlamaya da yardımcı olur. Değişkeni doğrudan belirli bir görünüme veya tüm görünümlere bağlayabilirsiniz. Örneğin, ihtiyaca göre görünüm oluşturucu dosyanızı saklamak için kendi dizininizi oluşturabilirsiniz. ve bu görünüm oluşturucu dosyasını Hizmet aracılığıyla görüntüleme ile etkileşim sağlar.

View composer yöntemi farklı bir yol kullanabilir, İlk örnek benzer görünebilir:

Bir App\Http\ViewComposersdizin oluşturabilirsiniz .

Servis sağlayıcı

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

Bundan sonra, bu sağlayıcıyı "sağlayıcılar" bölümünün altındaki config / app.php'ye ekleyin.

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

Bu yöntem yalnızca belirli Görünüm için yardımcı olabilir. Ancak ViewComposer'ı tüm görünümlerde tetiklemek istiyorsanız, bu tek değişikliği ServiceProvider'a uygulamalıyız.

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

Referans

Laravel Belgeleri

Daha Fazla Açıklama Laracast Bölümü

Benim açımdan hala belirsiz bir şey varsa, bana bildirin.


register()
Jonathan

@jonathan, işaret ettiğin için teşekkürler, ancak örnek sadece ilgilenilmesi gereken bölümleri içeriyor. verileri görünümle paylaşma perspektifi.
Safoor Safdar

filtreyi nereye koyuyorsunuz? Muhtemelen en doğru cevap, ara yazılım grupları kullanmaktır laravel.com/docs/5.3/middleware#middleware-groups veya global middleware
Toskan,

7
Bu iyi bir fikir değil, View composers her bir görünüm için composer örneğini oluşturur; bu, 1000 kez döngü çalıştırırsanız, 1000 besteci örneği oluşturulur ve 1000 kez tetikleme olayı işlenir, bu da istediğiniz bir şey değildir.
Rıza Shadman

4
@RezaShadman doğru! Bunu zor yoldan öğrendim. Uygulamam, araştırmak için laravel-debugbar aracını kurana kadar çok yavaş çalışıyordu. Sonra, tek bir sayfa yüklemesi için yaklaşık 15 kez yürütüldüğü 8 sorgunun tamamının yapıldığını fark ettim. Bunun nedeni, dahil edilen her blade dosyası için görünüm oluşturucunun çağrılacak olmasıdır. Yani yıldız işaretini kullanıyorsanız *. Eğer kullanmıyorsanız, *o zaman iyi olmalısınız.
Syclone

66

Kendi servis sağlayıcınızı oluşturabilir ( ViewServiceProvideradı yaygındır) veya mevcut olanı kullanabilirsiniz AppServiceProvider.

Seçtiğiniz sağlayıcıda, kodunuzu önyükleme yöntemine yerleştirin.

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

Bu, $datatüm görünümlerinizde bir değişkeni erişilebilir hale getirecektir .

Bunun yerine cephe yerine yardımcısı, değişim kullanmak istiyorsanız view()->için View::ancak sahip unutmayın use View;dosyanızın üstünde.


Teşekkürler, harika çalışıyor. Önyükleme işlevi bu tür şeyler için mi yoksa kendi servis sağlayıcımı oluşturmanızı önerirsiniz?
Ragnarsson

2
Paylaşacak yalnızca bir veya iki şeyiniz varsa, bunu koymak AppServiceProvidersorun değil, ancak bundan daha fazlasına sahipseniz, yeni bir sağlayıcı oluşturmayı düşünmelisiniz.
Marwelln

Çalışıyordu ama bugün işe yaramadığını görüyorum! kullanmak composer updateda çalışmıyor. Aslında hiç ateşlemiyor boot(). İki değişkeni paylaşmam gerekiyor.
itsazzad

11
Veri tabanı kayıtlarını alıyorsanız bunun işe yaramayacağını unutmayın, çünkü bu, geçişleri gerçekleştirmeden önce çağrılacaktır. Yani temelde veritabanı kayıtlarını var olmadan önce almaya çalışıyorsunuz. En azından benim için durum böyle görünüyor.
lorey

1
Ne yazık ki bu, oturum açmış bir kullanıcının Auth :: user () paylaşımında işe yaramıyor gibi görünüyor, Safoor'un bunun altındaki 1 numaralı cevabı :)
Stan Smulders

11

Bunu en kolay olanı buldum. Yeni bir sağlayıcı oluşturun ve '*'tüm görünümlere eklemek için joker karakteri kullanın. 5.3'te de çalışır :-)

<?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
Bu sağlayıcıyı config / uygulamanızdaki sağlayıcı dizisine ekleyin "App \ Providers \ ViewServiceProvider :: class,"
Nadeem0035

8

En iyi yol, değişkeni kullanarak paylaşmaktır. View::share('var', $value);

Kullanarak oluşturmayla ilgili sorunlar "*":

Aşağıdaki yaklaşımı düşünün:

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

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

Örnek bir bıçak görünümünden:

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

Ne oluyor?

  • GlobalComposerSınıf örneği 1000 kullanarak kez App::make.
  • Olay 1000 kez composing:some_partial_view_to_display_iele alınır .
  • composeİçeride fonksiyon GlobalComposersınıfında 1000 kez denir.

Ancak kısmi görünümün some_partial_view_to_display_ioluşturduğu değişkenlerle hiçbir ilgisi yoktur, GlobalComposerancak oluşturma süresini büyük ölçüde artırır.

En iyi yaklaşım?

View::shareGruplanmış bir ara katman yazılımı boyunca kullanma .

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

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

});

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

Güncelleme

Ara yazılım ardışık düzeni üzerinden hesaplanan bir şey kullanıyorsanız , uygun olayı dinleyebilir veya görünüm paylaşım ara yazılımını ardışık düzenin en altına yerleştirebilirsiniz.


4

Belgelerde:

Tipik olarak, bir servis sağlayıcının önyükleme yöntemi içinde paylaşım yöntemine çağrı yaparsınız. Bunları AppServiceProvider'a eklemekte veya barındırmak için ayrı bir servis sağlayıcı oluşturmakta özgürsünüz.

Marwelln'e katılıyorum, sadece AppServiceProviderönyükleme işlevine koyun :

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

Diğer "global" olmayan değişkenlerle karışıklık veya hatalardan kaçınmak için değişken için belirli bir ad kullanmanızı öneririm.


3

Dokümantasyon https://laravel.com/docs/5.4/views#view-composers duyuluyor ama ben onu parçalayacağım

  1. Uygulamanızın kök dizininde app \ Providers dizinini arayın ve ComposerServiceProvider.php dosyasını oluşturun ve aşağıdaki metni kopyalayıp içine yapıştırın ve kaydedin.

    <?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. Uygulamanızın kökünden Config / app.php dosyasını açın ve dosyadaki Sağlayıcılar bölümünü arayın ve bu 'App \ Providers \ ComposerServiceProvider'ı kopyalayıp diziye yapıştırın.

Bunu yaparak Composer Servis Sağlayıcısını oluşturduk. Uygulamanızı http: // alanınız / bir şey / profil gibi Profil görünümüyle çalıştırdığınızda , hizmet sağlayıcı ComposerServiceProvider çağrılır ve App \ Http \ ViewComposers \ ProfileComposer sınıfı aşağıdaki kod nedeniyle Composer yöntemini çağırarak başlatılır. önyükleme yöntemi veya işlevi.

 // Using class based composers...
 View::composer(
   'profile', 'App\Http\ViewComposers\ProfileComposer'
 );
  1. Uygulamanızı yenilerseniz, App \ Http \ ViewComposers \ ProfileComposer sınıfı henüz mevcut olmadığından bir hata alırsınız . Şimdi onu oluşturalım.

Dizin yolu app / Http'ye gidin

  • ViewComposers adlı dizini oluşturun

  • ProfileComposer.php dosyasını oluşturun .

    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());
        }
    }

Şimdi görünümünüze gidin veya bu durumda Profile.blade.php ve ekleyin

{{ $count }}

ve bu, profil sayfasındaki kullanıcı sayısını gösterecektir.

Sayıyı tüm sayfalarda göstermek için değiştirin

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

için

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

<? php ve ad alanı Uygulaması \ Http \ ViewComposers; Illuminate \ Contracts \ View \ View kullanın;
ProfileComposer.php



1

Yapılandırma klasörünüzün içinde bir php dosyası oluşturabilirsiniz, örneğin aşağıdaki içeriğe sahip "değişken.php":

<?php

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

Şimdi tüm görünümlerin içinde, istediğiniz gibi kullanabilirsiniz

config('variable.versionNumber')

Bazı durumlarda bu şekilde yapıyorum, çünkü bilgi gerçekten küreseldir ve ona her yerden erişebilirsiniz. Bu nedenle, yapılandırma dosyasını "global.php" olarak adlandırıyorum ve oraya kodumun diğer tüm bölümlerinde erişilebilir olmasını istediğim her şeyi koyuyorum. Tek sınırlama, bunun statik veriler için olması ve önbelleğe alınmasıdır. Sürekli değişen verileriniz varsa bu şekilde kullanılmamalıdır.
eResourcesInc

1

1) (app \ Providers \ AppServiceProvider.php) içinde

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

2) Kullanıcı Modelinizde

  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) Sizin Görüşünüzde

 {{ $var_messages }}

0

Laravel 5.6 yöntemi: https://laravel.com/docs/5.6/views#passing-data-to-views

Örnek, bir model koleksiyonunun tüm görünümlerle paylaşılmasıyla (AppServiceProvider.php):

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

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

}

2
Bu, boş bir veritabanı ile yeni bir uygulama oluşturmaya çalışıyorsanız sorunlara neden olacaktır.
Chris Herbert

0

İki seçeneğiniz var:

1. App \ Providers \ AppServiceProvider'da Önyükleme işlevi ile paylaşın

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

Ve herhangi bir görünüm dosyasında $ key değişkenine erişin.

Not: Mevcut Oturum, Yetkilendirme, Yönlendirme verilerine buradan erişemeyeceğinizi unutmayın. Bu seçenek yalnızca statik verileri paylaşmak istiyorsanız iyidir. Mevcut kullanıcı, rota veya herhangi bir özel oturum değişkenine dayalı olarak bazı verileri paylaşmak istediğinizi varsayalım, bununla yapamayacaksınız.

  1. Yardımcı sınıfın kullanımı Uygulamanızın herhangi bir yerinde bir yardımcı sınıf oluşturun ve bunu config klasöründeki app.php dosyasındaki Alias ​​dizisine kaydedin.

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

ve App klasöründeki HelperClass klasöründe Helper.php oluşturun

namespace App\HelperClass;

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

ve istediğiniz yerden erişin Helper::Sample()

Burada Yetkilendirme, Yol, Oturum veya diğer sınıfları kullanmakla kısıtlanmayacaksınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.