在 laravel 中动态填充下拉列表的有效方法
Efficient way to populate drop-down dynamically in laravel
我有多个数据库表,每个表都填充一个下拉列表,关键是每个下拉列表都会影响下一个下拉列表。
我的意思是,如果我 select 第一个下拉列表中的一个项目,下一个下拉列表值会在 selected 项目上发生变化,这意味着它们是相关的,并且它们会在每个下拉项目变化时动态填充.
我知道这效率不高,需要重构,所以我很乐意向我指出填充这些下拉菜单的正确方法。
这是控制器代码:
<?php
use App\Http\Controllers\Controller;
use App\Models\County;
use App\Models\OutDoorMedia;
use App\Models\Province;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
class FiltersController extends Controller
{
protected static $StatusCode = 0;
protected static $Msg = '';
protected static $Flag = false;
public function index(Request $request)
{
try {
$validator = Validator::make($request->all(), [
'province_id' => 'exists:province,id',
'county_id' => 'exists:county,id',
'media_type' => Rule::in([MEDIA_TYPE_BILLBOARD, MEDIA_TYPE_OUTDOOR_MONITOR, MEDIA_TYPE_INDOOR_MONITOR, MEDIA_TYPE_STAND, MEDIA_TYPE_STRABOARD, MEDIA_TYPE_BRAND_BOARD]),
'media_status' => Rule::in([MEDIA_STATUS_AVAILABLE, MEDIA_STATUS_NEGOTIATING, MEDIA_STATUS_ASSIGNED, MEDIA_STATUS_ARCHIVE]),
'category_id' => 'exists:category_list,id',
]);
if ($validator->fails()) {
abort(400, $validator->errors()->first());
} else {
//############################# Input Filters ####################################
$province_id = $request->has('province_id') ? $request->province_id : null;
$county_id = $request->has('county_id') ? $request->county_id : null;
$media_type = $request->has('media_type') ? $request->media_type : null;
$location = $request->has('location') ? $request->location : null;
$media_status = $request->has('media_status') ? $request->media_status : null;
$category_id = $request->has('category_id') ? $request->category_id : null;
//this flag is for detecting if user is requesting from "advertiser my order" to ignore some concitions
$advertiser_my_orders = ($request->has('my_orders') && $request->my_orders == 'true') ? true : false;
$province_ids = [];
$county_ids = [];
//############################# Media Owner Filters ####################################
//offline section filters
if (!is_null($province_id) && Province::whereId($request->province_id)->exists()) {
//check correction of county id
if (!is_null($county_id) && County::whereId($county_id)->whereProvinceId($province_id)->exists()) {
$media_owner_ODM_Provinces = Province::whereHas('media')->get()->toArray();
$media_owner_ODM_Provinces_Counties = County::whereProvinceId($province_id)
->whereHas('county_media')->get()->toArray();
foreach ($media_owner_ODM_Provinces as $key => $province) {
if ($province['id'] == $province_id) {
$media_owner_ODM_Provinces[$key]['county'] = $media_owner_ODM_Provinces_Counties;
}
}
$media_owner_ODM_locations = OutDoorMedia::whereProvinceId($province_id)->whereCountyId($county_id)->groupBy('location')->pluck('location')->toArray();
$media_owner_ODM_media_types = OutDoorMedia::whereProvinceId($province_id)->whereCountyId($county_id)->whereIn('location', $media_owner_ODM_locations)->groupBy('media_type')->pluck('media_type')->toArray();
$media_owner_ODM_media_Status = OutDoorMedia::whereProvinceId($province_id)->whereCountyId($county_id)->whereIn('media_type', $media_owner_ODM_media_types)->groupBy('status')->pluck('status')->toArray();
} else {
$media_owner_ODM_Provinces = Province::whereHas('media')->with(['county' => function ($query) {
$query->whereHas('county_media');
}])->get()->toArray();
$media_owner_ODM_locations = OutDoorMedia::whereProvinceId($province_id)->groupBy('location')->pluck('location')->toArray();
$media_owner_ODM_media_types = OutDoorMedia::whereProvinceId($province_id)->whereIn('location', $media_owner_ODM_locations)->groupBy('media_type')->pluck('media_type')->toArray();
$media_owner_ODM_media_Status = OutDoorMedia::whereProvinceId($province_id)->whereIn('media_type', $media_owner_ODM_media_types)->groupBy('status')->pluck('status')->toArray();
}
} else {
$media_owner_ODM_Provinces = Province::whereHas('media')->with(['county' => function ($query) {
$query->whereHas('county_media');
}])->get()->toArray();
foreach ($media_owner_ODM_Provinces as $province) {
$province_ids[] = $province['id'];
foreach ($province['county'] as $county) {
$county_ids[] = $county['id'];
}
}
$media_owner_ODM_locations = OutDoorMedia::whereIn('province_id', $province_ids)->whereIn('county_id', $county_ids)->groupBy('location')->pluck('location')->toArray();
$media_owner_ODM_media_types = OutDoorMedia::whereIn('province_id', $province_ids)->whereIn('county_id', $county_ids)->whereIn('location', $media_owner_ODM_locations)->groupBy('media_type')->pluck('media_type')->toArray();
$media_owner_ODM_media_Status = OutDoorMedia::whereIn('province_id', $province_ids)->whereIn('county_id', $county_ids)->whereIn('media_type', $media_owner_ODM_media_types)->groupBy('status')->pluck('status')->toArray();
}
$media_owner_offline = [
'provinces' => $media_owner_ODM_Provinces,
'media_status' => $media_owner_ODM_media_Status,
'location' => $media_owner_ODM_locations,
'media_type' => $media_owner_ODM_media_types,
];
$filters['media_owner']['offline'] = $media_owner_offline;
self::$StatusCode = 200;
self::$Msg = $filters;
self::$Flag = true;
}
} catch (\Exception $e) {
//=========== Get Error Exception Message ============
self::$StatusCode = 400;
self::$Msg = $e->getMessage();
self::$Flag = false;
return $this->CustomeJsonResponse(self::$Flag, self::$StatusCode, self::$Msg);
//=========== Get Error Exception Message ============
} finally {
return $this->CustomeJsonResponse(self::$Flag, self::$StatusCode, self::$Msg);
}
}
}
仅供参考:我正在使用 laravel 5.3 框架。
以下是您应该注意的事项。
首先,如果您验证了 province_id,那么就没有必要在您的代码中仔细检查它。所以你应该删除
Province::whereId($request->province_id)->exists()
第二个是,Laravel 有 ->when eloquent 方法可以帮助您减少空值的 if else 语句,如果给定参数有空值,它不会影响询问。
https://laravel.com/docs/5.8/queries#conditional-clauses
第三,我建议您使用Laravel 资源来转换您从API 中的数据库中获取的数据。
https://laravel.com/docs/5.8/eloquent-resources
这是你的一小部分代码的更好版本,我认为有了建议的提示和这段代码,你可以重构它:
class TestController extends Controller
{
const DEFAULT_COUNTRY_ID = '10';
public $request;
public function something(Request $request)
{
// Put Validations ...
$this->request = $request;
OutDoorMedia::when('province_id', function ($query) {
return $query->where('province_id', $this->request->province_id);
})
->when('country_id', function ($query) {
// if country_id exists
return $query->where('country_id', $this->request->country_id);
}, function ($query) {
// else of above if (country_id is null ...)
return $query->where('country_id', self::DEFAULT_COUNTRY_ID);
})
->get();
}
}
这只是一个示例,您可以使用这种方式来重构您的代码库。
我有多个数据库表,每个表都填充一个下拉列表,关键是每个下拉列表都会影响下一个下拉列表。
我的意思是,如果我 select 第一个下拉列表中的一个项目,下一个下拉列表值会在 selected 项目上发生变化,这意味着它们是相关的,并且它们会在每个下拉项目变化时动态填充.
我知道这效率不高,需要重构,所以我很乐意向我指出填充这些下拉菜单的正确方法。
这是控制器代码:
<?php
use App\Http\Controllers\Controller;
use App\Models\County;
use App\Models\OutDoorMedia;
use App\Models\Province;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
class FiltersController extends Controller
{
protected static $StatusCode = 0;
protected static $Msg = '';
protected static $Flag = false;
public function index(Request $request)
{
try {
$validator = Validator::make($request->all(), [
'province_id' => 'exists:province,id',
'county_id' => 'exists:county,id',
'media_type' => Rule::in([MEDIA_TYPE_BILLBOARD, MEDIA_TYPE_OUTDOOR_MONITOR, MEDIA_TYPE_INDOOR_MONITOR, MEDIA_TYPE_STAND, MEDIA_TYPE_STRABOARD, MEDIA_TYPE_BRAND_BOARD]),
'media_status' => Rule::in([MEDIA_STATUS_AVAILABLE, MEDIA_STATUS_NEGOTIATING, MEDIA_STATUS_ASSIGNED, MEDIA_STATUS_ARCHIVE]),
'category_id' => 'exists:category_list,id',
]);
if ($validator->fails()) {
abort(400, $validator->errors()->first());
} else {
//############################# Input Filters ####################################
$province_id = $request->has('province_id') ? $request->province_id : null;
$county_id = $request->has('county_id') ? $request->county_id : null;
$media_type = $request->has('media_type') ? $request->media_type : null;
$location = $request->has('location') ? $request->location : null;
$media_status = $request->has('media_status') ? $request->media_status : null;
$category_id = $request->has('category_id') ? $request->category_id : null;
//this flag is for detecting if user is requesting from "advertiser my order" to ignore some concitions
$advertiser_my_orders = ($request->has('my_orders') && $request->my_orders == 'true') ? true : false;
$province_ids = [];
$county_ids = [];
//############################# Media Owner Filters ####################################
//offline section filters
if (!is_null($province_id) && Province::whereId($request->province_id)->exists()) {
//check correction of county id
if (!is_null($county_id) && County::whereId($county_id)->whereProvinceId($province_id)->exists()) {
$media_owner_ODM_Provinces = Province::whereHas('media')->get()->toArray();
$media_owner_ODM_Provinces_Counties = County::whereProvinceId($province_id)
->whereHas('county_media')->get()->toArray();
foreach ($media_owner_ODM_Provinces as $key => $province) {
if ($province['id'] == $province_id) {
$media_owner_ODM_Provinces[$key]['county'] = $media_owner_ODM_Provinces_Counties;
}
}
$media_owner_ODM_locations = OutDoorMedia::whereProvinceId($province_id)->whereCountyId($county_id)->groupBy('location')->pluck('location')->toArray();
$media_owner_ODM_media_types = OutDoorMedia::whereProvinceId($province_id)->whereCountyId($county_id)->whereIn('location', $media_owner_ODM_locations)->groupBy('media_type')->pluck('media_type')->toArray();
$media_owner_ODM_media_Status = OutDoorMedia::whereProvinceId($province_id)->whereCountyId($county_id)->whereIn('media_type', $media_owner_ODM_media_types)->groupBy('status')->pluck('status')->toArray();
} else {
$media_owner_ODM_Provinces = Province::whereHas('media')->with(['county' => function ($query) {
$query->whereHas('county_media');
}])->get()->toArray();
$media_owner_ODM_locations = OutDoorMedia::whereProvinceId($province_id)->groupBy('location')->pluck('location')->toArray();
$media_owner_ODM_media_types = OutDoorMedia::whereProvinceId($province_id)->whereIn('location', $media_owner_ODM_locations)->groupBy('media_type')->pluck('media_type')->toArray();
$media_owner_ODM_media_Status = OutDoorMedia::whereProvinceId($province_id)->whereIn('media_type', $media_owner_ODM_media_types)->groupBy('status')->pluck('status')->toArray();
}
} else {
$media_owner_ODM_Provinces = Province::whereHas('media')->with(['county' => function ($query) {
$query->whereHas('county_media');
}])->get()->toArray();
foreach ($media_owner_ODM_Provinces as $province) {
$province_ids[] = $province['id'];
foreach ($province['county'] as $county) {
$county_ids[] = $county['id'];
}
}
$media_owner_ODM_locations = OutDoorMedia::whereIn('province_id', $province_ids)->whereIn('county_id', $county_ids)->groupBy('location')->pluck('location')->toArray();
$media_owner_ODM_media_types = OutDoorMedia::whereIn('province_id', $province_ids)->whereIn('county_id', $county_ids)->whereIn('location', $media_owner_ODM_locations)->groupBy('media_type')->pluck('media_type')->toArray();
$media_owner_ODM_media_Status = OutDoorMedia::whereIn('province_id', $province_ids)->whereIn('county_id', $county_ids)->whereIn('media_type', $media_owner_ODM_media_types)->groupBy('status')->pluck('status')->toArray();
}
$media_owner_offline = [
'provinces' => $media_owner_ODM_Provinces,
'media_status' => $media_owner_ODM_media_Status,
'location' => $media_owner_ODM_locations,
'media_type' => $media_owner_ODM_media_types,
];
$filters['media_owner']['offline'] = $media_owner_offline;
self::$StatusCode = 200;
self::$Msg = $filters;
self::$Flag = true;
}
} catch (\Exception $e) {
//=========== Get Error Exception Message ============
self::$StatusCode = 400;
self::$Msg = $e->getMessage();
self::$Flag = false;
return $this->CustomeJsonResponse(self::$Flag, self::$StatusCode, self::$Msg);
//=========== Get Error Exception Message ============
} finally {
return $this->CustomeJsonResponse(self::$Flag, self::$StatusCode, self::$Msg);
}
}
}
仅供参考:我正在使用 laravel 5.3 框架。
以下是您应该注意的事项。
首先,如果您验证了 province_id,那么就没有必要在您的代码中仔细检查它。所以你应该删除
Province::whereId($request->province_id)->exists()
第二个是,Laravel 有 ->when eloquent 方法可以帮助您减少空值的 if else 语句,如果给定参数有空值,它不会影响询问。 https://laravel.com/docs/5.8/queries#conditional-clauses
第三,我建议您使用Laravel 资源来转换您从API 中的数据库中获取的数据。 https://laravel.com/docs/5.8/eloquent-resources
这是你的一小部分代码的更好版本,我认为有了建议的提示和这段代码,你可以重构它:
class TestController extends Controller
{
const DEFAULT_COUNTRY_ID = '10';
public $request;
public function something(Request $request)
{
// Put Validations ...
$this->request = $request;
OutDoorMedia::when('province_id', function ($query) {
return $query->where('province_id', $this->request->province_id);
})
->when('country_id', function ($query) {
// if country_id exists
return $query->where('country_id', $this->request->country_id);
}, function ($query) {
// else of above if (country_id is null ...)
return $query->where('country_id', self::DEFAULT_COUNTRY_ID);
})
->get();
}
}
这只是一个示例,您可以使用这种方式来重构您的代码库。