【问题标题】:I'm having trouble creating some basic filtering using Laravel我在使用 Laravel 创建一些基本过滤时遇到问题
【发布时间】:2018-08-14 00:41:33
【问题描述】:

我的索引页面显示我的图像表中的所有图像,最新提交的图像位于顶部。我正在尝试添加一些基本过滤,以便我可以掌握这个概念,但我做错了。我的想法是:

添加 2 个带有 URL 的 <a> 元素到 www.domain.comwww.domain.com/ascending。如果用户访问www.domain.com,图片将按降序显示,如果用户访问www.domain.com/ascending,则图像将按升序显示。

然后我让我的主路由Route::get('/', 'PagesController@index')->name('home'); 有一个可选参数,例如Route::get('/{filter?}', 'PagesController@index')->name('home');

基于可选参数,我将向视图发送不同的$images 变量:

public function index($filter){    
    switch($filter) {
        case 'ascending'    : $images = Image::orderBy('created_at', 'asc')->get();break;
        default             : $images = Image::orderBy('created_at', 'desc')->get();
    }

    return view('home', ['images' => $images]);
}

当我这样做时,到目前为止我遇到了 2 个问题:

首先,当我转到www.domain.com 时,我得到"Type error: Too few arguments to function App\Http\Controllers\PagesController::index(), 0 passed and exactly 1 expected"

其次,在将可选参数添加到路由Route::get('/{filter?}', 'PagesController@index')->name('home'); 之后,即使我要去http://example.com/adminhttp://example.com/albums 之类的URL,我也会发送到我的索引页面。

我相信会发生这种情况,因为我的代码假定 /admin/albums 是我的 http://example.com 网址中的可选参数,而不是应有的单独网址。

Route::get('/{filter?}', 'PagesController@index')->name('home');
Route::get('/image/{id}', 'PagesController@specificImage')->name('specificImage');
Route::get('/tags', 'PagesController@tags')->name('tags');

所以即使我去标签路由,也会显示索引视图而不是标签视图。

如果有人能告诉我如何实现这个基本过滤,我将不胜感激。

【问题讨论】:

    标签: php laravel laravel-5


    【解决方案1】:

    你可以这样做 www.domain.com?orderby=asc

    Route::get('/', 'PagesController@index')->name('home');
    
    public function index(Request $request){
    
      $images = array();
    
      $images = Image::orderBy('created_at', $request->get('orderBy') ?? 'desc')->get();
    
      return view('home', ['images' => $images]);
    }
    

    【讨论】:

    • 设置$order = $request->get('orderBy') ?? "desc"; 并完全避免if($order) 子句不是更有意义吗? DRY 原则等等。
    • 如果你是对的,我会在我没有注意到的时候纠正它,感谢@TimLewis
    • 尽管$request->get('orderBy') ?? 'desc' 可以简化为:$request->get('orderBy', 'desc') 但它有一个错误,因为它只检查orderBy 的值是否为空,它不检查该值是否等于到“降级”。因此,如果我传递 'show' 或除 'asc' 或 'desc' 之外的任何任意值,它将引发错误。这就是为什么@RicardoCastillo 先生可以很好地解释您的代码的作用以及它如何解决 OP 的问题
    • 出于好奇,为什么要设置 $images = array();第一?
    • @Bobimaru 我喜欢声明我所有的变量之前只用于那个
    【解决方案2】:

    我建议您在这种情况下使用 get params 以避免 url 冲突。所以请求/ 现在应该是

    /?order=asc/?order=desc

    而是切换 get 参数 order 以知道是按降序还是升序显示页面。

    【讨论】:

      【解决方案3】:

      首先,在这种情况下,使用查询参数最适合过滤,而不是使用两个(或更多)url 端点。

      但是,如果您想坚持自己的实施,则需要做的事情很少:

      1. 声明你的路线不带斜线,例如:

          Route::get('{filter?}', 'PagesController@index')->name('home') 
        

        虽然不太确定这是否有什么不同,但我个人要注意一些事情(到处都是斜线)

      2. 通过在路由声明后使用where(),使用具有限制值的可选路径变量:

        Route::get('{filter?}', 'PagesController@index')->name('home')->where('filter', 'ascending|');
        

        它接受升序或什么都不接受。

      3. 将默认参数传递给您的控制器方法:

        public function index($filter = null)
        {
            .....
        }
        

        以防万一没有通过。这是使用可选路径变量时要注意的重点之一。

      最后,您可以在查询前使用三元运算符完全避免if 语句:

      public function index($filter = null){    
          $order = $filter === 'ascending' ? 'asc' : 'desc';
      
          $images = Image::orderBy('created_at', $order)->get();
      
          return view('home', ['images' => $images]);
      }
      

      【讨论】:

      • 哦,不,我不太喜欢我的实现而不是查询参数,坦率地说,我不知道我可以使用查询参数之类的东西。我只想遵循最好的约定。
      • 没关系。那么其他答案应该对你有帮助。否则,以防万一需要使用路径变量,那么这个答案很有用。
      猜你喜欢
      • 2013-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多