Laravel - 背包选择依赖于另一个选择
Posted
技术标签:
【中文标题】Laravel - 背包选择依赖于另一个选择【英文标题】:Laravel - Backpack select dependent from another select 【发布时间】:2020-10-09 14:54:43 【问题描述】:我最近在我的 Laravel 项目中安装了 Laravel Backpack
admin。目前我正在努力。但我需要帮助。所以...
我想要什么:
我想要两个选择,第一个是Category
,第二个是Article
。所以Article
select 必须依赖于Category
select。还有Article
belongsTo
Category
。
类别-文章
Category 1 = [ Article 1, Article 2, Article 3 ]
Category 2 = [ Article 4, Article 5 ]
这只是显示哪个文章属于类别。例如,当我在category
上单击Category 1
选择时,在article
上选择它应该只显示Article 1, Article 2 and Article 3
。
我做了什么
我遵循了 Backpack 文档中的说明,在此 link 上为 Add a select2 field that depends on another field
。所以我首先做了什么:
我创建了两个表,Category
表和 Article
表。他们的模型:
class Category extends Model
use CrudTrait;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'categories';
protected $primaryKey = 'id';
// public $timestamps = false;
// protected $guarded = ['id'];
protected $fillable = ['title'];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
public function articles()
return $this->hasMany('App\Models\Article');
这是Category
模型,这是Article
模型:
class Article extends Model
use CrudTrait;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'articles';
protected $primaryKey = 'id';
// public $timestamps = false;
// protected $guarded = ['id'];
protected $fillable = ['title', 'category_id'];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function category()
return $this->belongsTo('App\Models\Category');
我在这两个模型之间建立了这样的关系。所以当我创建Article
时,它会显示我的标题,我必须从category select
中选择category_id
。
毕竟我做了Archive
表,这些是我的迁移:
Schema::create('archives', function (Blueprint $table)
$table->increments('id');
$table->string('title');
$table->bigInteger('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('categories');
$table->bigInteger('article_id')->unsigned();
$table->foreign('article_id')->references('id')->on('articles');
$table->timestamps();
);
还有我的Archive.php
模特:
class Archive extends Model
use CrudTrait;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'archives';
protected $primaryKey = 'id';
// public $timestamps = false;
// protected $guarded = ['id'];
protected $fillable = ['title', 'category', 'article'];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function category()
return $this->belongsTo('App\Models\Category');
public function article()
return $this->belongsTo('App\Models\Article');
然后我按照backpack docs
的指示进行操作。
这是我的ArchiveCrudController
:
public function setup()
/*
|--------------------------------------------------------------------------
| CrudPanel Basic Information
|--------------------------------------------------------------------------
*/
$this->crud->setModel('App\Models\Archive');
$this->crud->setRoute(config('backpack.base.route_prefix') . '/archive');
$this->crud->setEntityNameStrings('archive', 'archives');
$this->crud->setColumns(['title', 'category', 'article']);
$this->crud->addField([
'name' => 'title',
'type' => 'text',
'label' => "Archive title"
]);
$this->crud->addField([ // SELECT2
'label' => 'Category',
'type' => 'select',
'name' => 'category_id',
'entity' => 'category',
'attribute' => 'title',
]);
$this->crud->addField([ // select2_from_ajax: 1-n relationship
'label' => "Article", // Table column heading
'type' => 'select2_from_ajax',
'name' => 'article_id', // the column that contains the ID of that connected entity;
'entity' => 'article', // the method that defines the relationship in your Model
'attribute' => 'title', // foreign key attribute that is shown to user
'data_source' => url('api/article'), // url to controller search function (with /id should return model)
'placeholder' => 'Select an article', // placeholder for the select
'minimum_input_length' => 0, // minimum characters to type before querying results
'dependencies' => ['category'], // when a dependency changes, this select2 is reset to null
//'method' => ‘GET’, // optional - HTTP method to use for the AJAX call (GET, POST)
]);
/*
|--------------------------------------------------------------------------
| CrudPanel Configuration
|--------------------------------------------------------------------------
*/
// TODO: remove setFromDb() and manually define Fields and Columns
//$this->crud->setFromDb();
// add asterisk for fields that are required in ArchiveRequest
$this->crud->setRequiredFields(StoreRequest::class, 'create');
$this->crud->setRequiredFields(UpdateRequest::class, 'edit');
来自backpack docs
。然后我在App\Http\Controller
中创建了Api
文件夹,然后在其中创建了ArticleController
,如下所示:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Article;
use Illuminate\Http\Request;
class ArticleController extends Controller
public function index(Request $request)
$search_term = $request->input('q');
$form = collect($request->input('form'))->pluck('value', 'name');
$options = Article::query();
// if no category has been selected, show no options
if (! $form['category'])
return [];
// if a category has been selected, only show articles in that category
if ($form['category'])
$options = $options->where('category_id', $form['category']);
if ($search_term)
$results = $options->where('title', 'LIKE', '%'.$search_term.'%')->paginate(10);
else
$results = $options->paginate(10);
return $options->paginate(10);
public function show($id)
return Article::find($id);
我只是从docs
复制粘贴代码,但当然我根据需要更改了模型。
最后是我的routes
:
Route::get('api/article', 'App\Http\Controllers\Api\ArticleController@index');
Route::get('api/article/id', 'App\Http\Controllers\Api\ArticleController@show');
我将这些路由复制粘贴到我的web.php
中的routes
文件夹和custom.php
中的routes/backpack
文件夹中。
但是当我在Archive create
中选择类别时,没有articles
显示。
有人可以帮我解决这个问题吗?
【问题讨论】:
【参考方案1】:从背包 4.1 开始,您应该在依赖字段中包含 'include_all_form_fields' => true 属性。
【讨论】:
【参考方案2】:您的代码中有一些问题,我希望这能解决它们:
1- 在 ArchiveCrudController 中:确保具有 category_id 的依赖项不是 category ...
'dependencies' => ['category_id'],
$this->crud->addField([ // select2_from_ajax: 1-n relationship
'label' => "Article",
'type' => 'select2_from_ajax',
'name' => 'article_id',
'entity' => 'article',
'attribute' => 'title',
'data_source' => url('api/article'),
'placeholder' => 'Select an article',
'minimum_input_length' => 0, querying results
'dependencies' => ['category_id'],
//'method' => ‘GET’,
]);
2- 在存档模型 $fillable 中应该采用数据库列名而不是关系...
protected $fillable = ['title', 'category_id', 'article_id'];
3- 当你得到 $form 请求参数时,它带有名称 category_id 就像你在 Crud 中命名它不是(类别)
public function index(Request $request)
$search_term = $request->input('q');
$form = collect($request->input('form'))->pluck('value', 'name');
$options = Article::query();
// if no category has been selected, show no options
if (! $form['category_id'])
return [];
// if a category has been selected, only show articles in that category
if ($form['category_id'])
$options = $options->where('category_id', $form['category_id']);
if ($search_term)
$results = $options->where('title', 'LIKE', '%'.$search_term.'%')->paginate(10);
else
$results = $options->paginate(10);
return $options->paginate(10);
【讨论】:
以上是关于Laravel - 背包选择依赖于另一个选择的主要内容,如果未能解决你的问题,请参考以下文章