2015-04-25 49 views
6

我想知道是否有一種神奇的方法使用這樣的情景:如果我通過Ajax請求的控制器返回一個JSON對象調用頁面Laravel 5回JSON或視圖取決於如果AJAX或不

,否則它會返回一個視圖,我試圖在沒有改變每個方法的情況下在我的所有控制器上執行此操作。

例如我知道我能做到這一點:

if (Request::ajax()) return compact($object1, $object2); 
else return view('template', compact($object, $object2)); 

,但我有很多的控制器/方法,我喜歡改變基本行爲,而不是花我的時間來改變它們的所有。任何想法 ?

+1

恕我直言,你要實現的目標也不是沒有可能接觸到控制器的方法。我建議你使用@fungku的方法並調整你需要的方法。至少你有一個地方,然後再次改變你的控制器的響應行爲。 –

回答

4

最簡單的方法是製作一個在所有控制器之間共享的方法。

例子:

這是所有其他控制器擴展你的控制器類:

<?php namespace App\Http\Controllers; 

use Illuminate\Routing\Controller as BaseController; 

abstract class Controller extends BaseController 
{ 
    protected function makeResponse($template, $objects = []) 
    { 
     if (\Request::ajax()) { 
      return json_encode($objects); 
     } 

     return view($template, $objects); 
    } 
} 

這是延長它的控制器之一:

<?php namespace App\Http\Controllers; 

class MyController extends Controller 
{ 
    public function index() 
    { 
     $object = new Object1; 
     $object2 = new Object2; 

     return $this->makeResponse($template, compact($object, $object2)); 
    } 
} 

更新Laravel 5+

<?php 

namespace App\Http\Controllers; 

use Illuminate\Foundation\Bus\DispatchesJobs; 
use Illuminate\Routing\Controller as BaseController; 
use Illuminate\Foundation\Validation\ValidatesRequests; 
use Illuminate\Foundation\Auth\Access\AuthorizesRequests; 

class Controller extends BaseController 
{ 
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests; 

    protected function makeResponse($request, $template, $data = []) 
    { 
     if ($request->ajax()) { 
      return response()->json($data); 
     } 

     return view($template, $data); 
    } 
} 
<?php 

namespace App\Http\Controllers; 

use Illuminate\Http\Request; 

class MyController extends Controller 
{ 
    public function index(Request $request) 
    { 
     $object = new Object1; 
     $object2 = new Object2; 

     return $this->makeResponse($request, $template, compact($object, $object2)); 
    } 
} 
+0

而不是'if(\ Request :: ajax())',我可以使用if(\ Request :: isJson())'嗎?謝謝! –

+1

@RuChernChong你可以。或者你可以使用'\ Request :: ajax()','\ Request :: expectsJson()'或'\ Request :: wantsJson()',這取決於你想要的。 – ryanwinchester

1

有沒有神奇的,但你可以很容易地在3個步驟覆蓋ViewService:

1,創建視圖工廠(your_project_path/app/MyViewFactory.php

<?php 
/** 
* Created by PhpStorm. 
* User: panos 
* Date: 5/2/15 
* Time: 1:35 AM 
*/ 

namespace App; 

use Illuminate\View\Factory; 

class MyViewFactory extends Factory { 
    public function make($view, $data = array(), $mergeData = array()) 
    { 
     if (\Request::ajax()) { 
      return $data; 
     } 
     return parent::make($view, $data, $mergeData); 
    } 
} 

2.創建視圖服務提供商(your_project_path/app/providers/MyViewProvider.php

<?php namespace App\Providers; 

use App\MyViewFactory; 
use Illuminate\View\ViewServiceProvider; 

class MyViewProvider extends ViewServiceProvider { 

    /** 
    * Register the application services. 
    * 
    * @return void 
    */ 
    public function register() 
    { 
     parent::register(); 
    } 
    /** 
    * Overwrite original so we can register MyViewFactory 
    * 
    * @return void 
    */ 
    public function registerFactory() 
    { 
     $this->app->singleton('view', function($app) 
     { 
      // Next we need to grab the engine resolver instance that will be used by the 
      // environment. The resolver will be used by an environment to get each of 
      // the various engine implementations such as plain PHP or Blade engine. 
      $resolver = $app['view.engine.resolver']; 

      $finder = $app['view.finder']; 

      // IMPORTANT in next line you should use your ViewFactory 
      $env = new MyViewFactory($resolver, $finder, $app['events']); 

      // We will also set the container instance on this view environment since the 
      // view composers may be classes registered in the container, which allows 
      // for great testable, flexible composers for the application developer. 
      $env->setContainer($app); 

      $env->share('app', $app); 

      return $env; 
     }); 
    } 
} 

3.in your_project_path/config/app.php: 變化'Illuminate\View\ViewServiceProvider','App\Providers\MyViewProvider',

什麼該做:

它告訴你的應用程序使用另一個將在MyViewProvider.php 33線註冊您的視圖工廠 $env = new MyViewFactory($resolver, $finder, $app['events']); 收看提供商將檢查是否請求AJAX和返回,如果真或繼續使用原來的行爲 return parent::make($view, $data, $mergeData);MyViewFactory.php線19

希望這有助於你,

0

在laravel 5.1,這是最好的方法:

if (\Illuminate\Support\Facades\Request::ajax()) 
 
    return response()->json(compact($object1, $object2)); 
 

 
else 
 
    return view('template', compact($object, $object2));

相關問題