【问题标题】:AJAX request to Laravel resource controller, best practice对 Laravel 资源控制器的 AJAX 请求,最佳实践
【发布时间】:2018-12-03 12:47:48
【问题描述】:

我在 Laravel 中设置了一个资源控制器,索引函数如下:

public function index()
{
    if (!Auth::check()) {
        return redirect()->route('login');
    }
    $decks = Auth::user()->decks->sortByDesc('name');
    return view('decks.index')->with('decks', $decks);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
}

在另一个页面上,我还需要通过 AJAX 调用的 $decks 变量。现在我已经设置了一条到我的控制器的附加路由,我可以通过 GET 请求从中检索卡片组:

public function getDecks()
{
    if (!Auth::check()) {
        return;
    }
    $decks = Auth::user()->decks->sortByDesc('name');
    return response()->json($decks);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
}

我的问题:有没有办法通过直接向index 的请求获取$decks 变量,或者我的解决方案是可行的方法?

如果我向 index 发出 get 请求,我将获得 decks.index 视图的 HTML,但我如何访问(如果可能)$decks 变量?

我想我没有真正理解的是:$decks->with('decks', $decks) 语句中会发生什么?我知道我可以在该页面上使用刀片语法访问$decks,但是它从哪里访问数据,我也可以通过 AJAX 访问它吗?

【问题讨论】:

    标签: javascript ajax laravel get


    【解决方案1】:

    是的!您可以根据完成的请求类型返回不同的结果。不需要2条路线:

    public function index(Request $request)
    {
        $decks = Auth::user()->decks->sortByDesc('name');
    
        if ($request->ajax()) {
            return response()->json(['decks' => $decks]);
        } else {
            return view('decks.index')->with('decks', $decks);
        }
    }
    

    @Sven Hakvoort 是对的,你应该在路由定义中检查身份验证:

    Route::group(['middleware' => 'auth'], function () {
        Route::get('/decks', 'DecksController@index');
        // ... some other routes which requires authentication
    }
    

    【讨论】:

    • 啊,是的,你是对的。但是我仍然不建议这样做,因为惯例是 API 驻留在专用 API 路由中(例如,host/api/v1/....),混合使用这些是不好的做法。因此,我不会推荐这种方法,无论它是一个有效的解决方案
    • @SvenHakvoort 完全正确,但是,如果您使用 2 条路线,您还应该有一个服务来避免代码重复..
    • 是的,当然。我在回答中提到了这个简短的内容(但是作为一项功能,而不是一项服务)。但这绝对是最好的做法!
    【解决方案2】:

    您不能直接从索引路由中检索$decks。当您调用view(..)->with(...) 时,它会在内部传递给刀片模板处理器,该处理器也接收$decks 变量,然后在服务器端构建HTML,然后将“编译的”HTMl 返回给浏览器。因此,一旦服务器返回结果,$decks 变量就不再存在。由于这种行为,不可能做你想做的事。

    所以是的,您的解决方案是可行的方法,尽管您可能会考虑将 Auth::check() 包装在 middleware 中并将对 $decks 的调用移至单独的函数以简化您的代码。

    我希望这能回答您的问题,如果有任何不清楚的地方,请随时提问!

    【讨论】:

    • 感谢您的快速回答。
    【解决方案3】:

    您的解决方案是正确的方法。使用您的路由处理任何业务逻辑或数据检索通常不是一个好主意 - 首选使用控制器,这就是您正在做的事情。如果您想避免控制器中的if (Auth::check()) 语句,您可以像这样直接将auth 中间件添加到该路由。

    Route::get('example', 'YourController@index')->middleware('auth');
    

    关于->with('decks', $decks)的问题: 该函数将您的$decks 变量发送到要在刀片模板中呈现的视图。服务器使用该数据来呈现页面,然后丢弃该变量。如果您还希望能够使用 javascript 在您的页面上处理该数据,您可以在刀片模板中执行类似的操作。

    <script>
        var decks = {!!$decks->toJSON()!!};
    </script>
    

    【讨论】:

    • OP正在使用控制器,注意index函数和getDecks函数,所以部分答案无效;)
    • 另外,他不想在页面上使用他的 JS 中的数据。问题是他是否只能从该路由中检索 JSON
    • 是的,斯文是正确的。如果我对问题的表述具有误导性,我很抱歉。不过谢谢你的发言
    • 我知道 OP 正在使用控制器 - 这不是我在回答中所说的吗?我只是举例说明如何在路由中使用中间件。对不起,如果我误解了。是的,你对 JS 的看法是正确的——我知道这不是问题的确切答案——只是认为它可能是有用的信息——它不是,抱歉。
    猜你喜欢
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    相关资源
    最近更新 更多