Làm cách nào để truyền dữ liệu tới tất cả các chế độ xem trong Laravel 5?


125

Tôi muốn có một số dữ liệu mặc định có thể truy cập được trong tất cả các chế độ xem trong ứng dụng Laravel 5 của tôi.

Tôi đã cố gắng tìm kiếm nó nhưng chỉ tìm thấy kết quả cho Laravel 4. Tôi đã đọc tài liệu 'Chia sẻ dữ liệu với tất cả các lượt xem' ở đây nhưng tôi không thể hiểu phải làm gì. Nên đặt đoạn mã sau ở đâu?

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

Cảm ơn bạn đã giúp đỡ.


tốt, bạn cần mã khởi động để quản lý yêu cầu này?
Safoor Safdar

1
sử dụng View :: share trong một nhà cung cấp dịch vụ với kết quả của một cuộc gọi cơ sở dữ liệu sẽ lỗi ứng dụng khi chạy di chuyển db làm mới hoặc cố gắng chạy hoàng hôn với kết nối db không thể truy cập (câu chuyện dài, .env.dusk.local là chỉ được sử dụng sau khi nhà cung cấp dịch vụ được chạy). Như được đề cập dưới đây trong một bộ điều khiển cơ sở hoặc phần mềm trung gian là tốt nhất.
Andy lobel

Ngoài ra, hãy cẩn thận khi sử dụng các trình *soạn thảo chế độ xem, đặc biệt là nếu sử dụng truy vấn db, vì nó được chạy cho mọi chế độ xem phụ, thành phần, v.v., để cuối cùng bạn có thể chạy hàng trăm truy vấn không cần thiết, điều tốt nhất là sử dụng chế độ xem cơ bản, ví dụ như bố cục. ứng dụng sau đó chuyển dữ liệu xuống khi cần thiết.
Andy lobel

Câu trả lời:


220

Mục tiêu này có thể đạt được thông qua các phương pháp khác nhau,

1. Sử dụng BaseControll

Cách tôi muốn thiết lập mọi thứ, tôi tạo một BaseControllerlớp mở rộng riêng của Laravel Controllervà thiết lập nhiều thứ toàn cầu khác nhau ở đó. Tất cả các bộ điều khiển khác sau đó mở rộng từ BaseControllerchứ không phải Bộ điều khiển của 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. Sử dụng Bộ lọc

Nếu bạn biết rằng bạn muốn một cái gì đó được thiết lập để xem cho mọi yêu cầu trong toàn bộ ứng dụng, bạn cũng có thể thực hiện thông qua bộ lọc chạy trước yêu cầu - đây là cách tôi xử lý đối tượng Người dùng trong Laravel.

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

HOẶC LÀ

Bạn có thể xác định bộ lọc của riêng bạn

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

và gọi nó thông qua gọi bộ lọc đơn giản.

Cập nhật theo phiên bản 5. *

3. Sử dụng Middleware

Sử dụng View::sharevớimiddleware

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



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

4. Sử dụng Trình soạn nhạc Xem

Xem Trình soạn thảo cũng giúp liên kết dữ liệu cụ thể để xem theo nhiều cách khác nhau. Bạn có thể liên kết trực tiếp biến với chế độ xem cụ thể hoặc với tất cả các chế độ xem. Ví dụ, bạn có thể tạo thư mục của riêng mình để lưu trữ tệp soạn thảo chế độ xem theo yêu cầu. và các tệp soạn thảo chế độ xem này thông qua Dịch vụ cung cấp tương tác với chế độ xem.

Xem phương pháp soạn nhạc có thể sử dụng cách khác nhau, ví dụ đầu tiên có thể trông giống nhau:

Bạn có thể tạo một App\Http\ViewComposersthư mục.

Nhà cung cấp dịch vụ

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

Sau đó, thêm nhà cung cấp này vào config / app.php trong phần "nhà cung cấp".

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

Phương pháp này có thể giúp chỉ cho Chế độ xem cụ thể. Nhưng nếu bạn muốn kích hoạt ViewComposer cho tất cả các chế độ xem, chúng tôi phải áp dụng thay đổi duy nhất này cho ServiceProvider.

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

Tài liệu tham khảo

Tài liệu của Laravel

Để làm rõ hơn Tập phim Laracast

Nếu vẫn còn một cái gì đó không rõ ràng từ phía tôi, cho tôi biết.


Ví dụ của bạn thiếu register()phương thức - không phải là tùy chọn
Jonathan

@jonathan nhờ chỉ ra nó, nhưng ví dụ chỉ chứa những phần cần quan tâm. quan điểm để chia sẻ dữ liệu với xem.
Safoor Safdar

bạn đặt bộ lọc ở đâu? có lẽ câu trả lời đúng nhất hiện đang sử dụng các nhóm phần mềm trung gian laravel.com/docs/5.3/middleware#middleware-groups hoặc phần mềm trung gian toàn cầu
Toskan

7
Đây không phải là một ý tưởng hay, các nhà soạn nhạc View tạo ra cá thể nhà soạn nhạc cho mỗi chế độ xem riêng lẻ, điều đó có nghĩa là nếu bạn chạy một vòng lặp 1000 lần, 1000 trường hợp nhà soạn nhạc sẽ được tạo và 1000 lần sự kiện bắn được xử lý không phải là điều bạn muốn.
Reza Shadman

4
@RezaShadman là chính xác! Tôi đã học được điều này một cách khó khăn. Ứng dụng của tôi chạy rất chậm cho đến khi tôi cài đặt công cụ gỡ lỗi laravel để điều tra. Sau đó, tôi nhận ra rằng tất cả 8 truy vấn được thực hiện khoảng 15 lần cho một lần tải trang. Điều này là do trình soạn thảo chế độ xem sẽ được gọi cho mỗi tệp lưỡi được bao gồm. Đó là nếu bạn đang sử dụng dấu hoa thị *. Nếu bạn không sử dụng *thì bạn sẽ ổn thôi.
Lốc xoáy

66

Bạn có thể tạo nhà cung cấp dịch vụ của riêng mình ( ViewServiceProvidertên chung) hoặc bạn có thể sử dụng dịch vụ hiện có AppServiceProvider.

Trong nhà cung cấp đã chọn của bạn, đặt mã của bạn vào phương thức khởi động.

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

Điều này sẽ làm cho một $databiến có thể truy cập trong tất cả các quan điểm của bạn.

Nếu bạn muốn sử dụng mặt tiền thay vì người trợ giúp, hãy đổi view()->sang View::nhưng đừng quên có use View;ở đầu tệp của bạn.


Cảm ơn, làm việc tuyệt vời. Là chức năng khởi động dành cho loại điều này hay bạn khuyên bạn nên tạo nhà cung cấp dịch vụ của riêng tôi?
Ragnarsson

2
Nếu bạn chỉ có một hoặc hai điều để chia sẻ thì việc này AppServiceProvidersẽ ổn, nhưng nếu bạn có nhiều thứ hơn thế, bạn nên xem xét việc tạo một nhà cung cấp mới.
Marwelln

Nó đã hoạt động nhưng tôi chỉ thấy rằng nó không hoạt động ngày hôm nay! sử dụng composer updatecũng không hoạt động. Trên thực tế, nó không bắn boot()tất cả. Tôi cần chia sẻ hai biến.
itazzad

11
Xin lưu ý rằng điều này sẽ không hoạt động nếu bạn đang tìm nạp các bản ghi cơ sở dữ liệu vì điều này sẽ được gọi trước khi thực hiện di chuyển. Vì vậy, về cơ bản bạn đang cố gắng tìm nạp các bản ghi cơ sở dữ liệu trước khi chúng tồn tại. Ít nhất đó dường như là trường hợp của tôi.
truyền thuyết

1
Thật không may, điều này dường như không hoạt động với việc chia sẻ người dùng đã đăng nhập Auth :: user (), câu trả lời số 1 của Safoor, bên dưới câu hỏi này, :)
Stan Smulder

11

Tôi thấy đây là một trong những dễ dàng nhất. Tạo một nhà cung cấp mới và sử dụng '*'ký tự đại diện để đính kèm nó vào tất cả các chế độ xem. Hoạt động trong 5.3 cũng vậy :-)

<?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
Thêm nhà cung cấp này vào một loạt các nhà cung cấp trong cấu hình / ứng dụng của bạn "Ứng dụng \ Nhà cung cấp \ ViewServiceProvider :: class"
Nadeem0035

8

Cách tốt nhất là chia sẻ biến bằng cách sử dụng View::share('var', $value);

Các vấn đề với việc soạn thảo bằng cách sử dụng "*":

Xem xét phương pháp sau:

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

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

Từ chế độ xem lưỡi ví dụ:

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

Chuyện gì xảy ra

  • Các GlobalComposerlớp được khởi tạo 1000 lần sử dụng App::make.
  • Sự kiện này composing:some_partial_view_to_display_iđược xử lý 1000 lần.
  • Các composechức năng bên trong GlobalComposerlớp được gọi là 1000 lần.

Nhưng chế độ xem một phần some_partial_view_to_display_ikhông liên quan gì đến các biến được tạo bởi GlobalComposernhưng làm tăng đáng kể thời gian kết xuất.

Cách tiếp cận tốt nhất?

Sử dụng View::sharecùng với một phần mềm trung gian được nhóm lại.

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

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

});

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

Cập nhật

Nếu bạn đang sử dụng một cái gì đó được tính toán qua đường ống phần mềm trung gian, bạn có thể chỉ cần lắng nghe sự kiện thích hợp hoặc đặt phần mềm trung gian chia sẻ khung nhìn ở dưới cùng của đường ống.


4

Trong tài liệu:

Thông thường, bạn sẽ thực hiện các cuộc gọi đến phương thức chia sẻ trong phương thức khởi động của nhà cung cấp dịch vụ. Bạn có thể tự do thêm chúng vào AppServiceProvider hoặc tạo một nhà cung cấp dịch vụ riêng để chứa chúng.

Tôi đồng ý với Marwelln, chỉ cần đưa nó vào AppServiceProviderchức năng khởi động:

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

Tôi khuyên bạn nên sử dụng một tên cụ thể cho biến, để tránh những rắc rối hoặc sai lầm với các biến không 'toàn cầu' khác.


3

Tài liệu được nghe https://laravel.com/docs/5.4/view#view-composers nhưng tôi sẽ chia nhỏ nó

  1. Tìm ứng dụng thư mục \ Nhà cung cấp trong thư mục gốc của ứng dụng của bạn và tạo tệp ComposerServiceProvider.php và sao chép và dán văn bản bên dưới vào đó và lưu nó.

    <?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. Từ thư mục gốc của ứng dụng của bạn, hãy mở Config / app.php và tìm phần Nhà cung cấp trong tệp và sao chép và qua 'Ứng dụng \ Nhà cung cấp \ ComposerServiceProvider' này vào mảng.

Bằng cách này, chúng tôi đã tạo ra Nhà cung cấp dịch vụ soạn nhạc. Khi bạn chạy ứng dụng của mình với chế độ xem Hồ sơ như vậy http: // yourdomain / Something / profile , nhà cung cấp dịch vụ ComposerServiceProvider được gọi và lớp App \ http \ ViewComposers \ ProfileComposer sẽ ngay lập tức gọi phương thức Trình soạn thảo do mã bên dưới phương thức khởi động hoặc chức năng.

 // Using class based composers...
 View::composer(
   'profile', 'App\Http\ViewComposers\ProfileComposer'
 );
  1. Nếu bạn làm mới ứng dụng của mình, bạn sẽ gặp lỗi vì lớp Ứng dụng \ http \ ViewComposers \ ProfileComposer chưa tồn tại. Bây giờ hãy tạo nó.

Đi đến ứng dụng đường dẫn thư mục / http

  • Tạo thư mục có tên ViewComposers

  • Tạo tập tin 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());
        }
    }

Bây giờ hãy vào chế độ xem của bạn hoặc trong trường hợp này là Profile.blade.php và thêm

{{ $count }}

và điều đó sẽ hiển thị số lượng người dùng trên trang hồ sơ.

Để hiển thị số lượng trên tất cả các trang thay đổi

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

Đến

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

<? php và không gian tên Ứng dụng \ http \ ViewComposers; sử dụng Illuminate \ Hợp đồng \ View \ View; bị thiếu trong
ProfileComposer.php



1

Trong thư mục cấu hình của bạn, bạn có thể tạo một tên tệp php, ví dụ "biến.php" với nội dung bên dưới:

<?php

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

Bây giờ bên trong tất cả các chế độ xem bạn có thể sử dụng nó như

config('variable.versionNumber')

Tôi làm theo cách này trong một số trường hợp, vì thông tin thực sự mang tính toàn cầu và bạn có thể truy cập nó từ bất cứ đâu. Vì lý do đó, tôi gọi tệp cấu hình là "global.php" và tôi đặt bất cứ thứ gì vào đó mà tôi muốn có thể truy cập được trong tất cả các phần khác của mã. Chỉ có một hạn chế là đây là dữ liệu tĩnh và được lưu trữ. Không nên sử dụng theo cách này nếu bạn liên tục thay đổi dữ liệu.
eResourceInc

1

1) Trong (ứng dụng \ Nhà cung cấp \ AppServiceProvider.php)

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

2) trong Mô hình người dùng của bạn

  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) trong quan điểm của bạn

 {{ $var_messages }}

0

Phương pháp Laravel 5.6: https://laravel.com/docs/5.6/view#passing-data-to-view

Ví dụ, với việc chia sẻ bộ sưu tập mô hình cho tất cả các chế độ xem (AppServiceProvider.php):

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

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

}

2
Điều này sẽ gây ra vấn đề nếu bạn đang cố gắng tạo một ứng dụng mới với cơ sở dữ liệu trống.
Chris Herbert

0

Bạn có hai lựa chọn:

1.Share thông qua chức năng Boot trong App \ Providers \ AppServiceProvider

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

Và truy cập biến $ key trong bất kỳ tệp xem nào.

Lưu ý: Hãy nhớ rằng bạn không thể truy cập dữ liệu Phiên, Xác thực, Lộ trình hiện tại tại đây. Tùy chọn này chỉ tốt nếu bạn muốn chia sẻ dữ liệu tĩnh. Giả sử bạn muốn chia sẻ một số dữ liệu dựa trên người dùng hiện tại, tuyến đường hoặc bất kỳ biến phiên tùy chỉnh nào bạn sẽ không thể thực hiện với điều này.

  1. Sử dụng lớp trình trợ giúp Tạo lớp trình trợ giúp ở bất kỳ đâu trong ứng dụng của bạn và đăng ký nó trong mảng Bí danh trong tệp app.php trong thư mục cấu hình.

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

và tạo Helper.php trong thư mục HelperClass trong thư mục Ứng dụng

namespace App\HelperClass;

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

và truy cập nó ở bất cứ đâu như Helper::Sample()

Bạn sẽ không bị hạn chế ở đây để sử dụng Auth, Tuyến đường, Phiên hoặc bất kỳ lớp nào khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.