LARAVEL - 使用 Route::resource 生成路由时无法使用销毁路由
LARAVEL - Unable to use destroy route when generating it with Route::resource
上下文。我在 Laravel 8 工作,我使用 DataTables 插件显示数据库中的记录。正如您将在代码中看到的那样,我创建了所有用于执行 CRUD 的路由:Route::resource('animal', 'AnimalController')。这会为 DESTROY 方法生成一个路径,如下所示:animal/{id}
问题。当我按下特定记录的删除按钮时,记录被删除了,很好,但是浏览器控制台 returns 出现此错误:“此路由不支持 DELETE 方法。支持的方法:GET、HEAD、POST",因此 Javascript 被破坏,记录被删除的警告永远不会显示。如果我将请求类型更改为 POST 而不是 DELETE,错误会告诉我不支持 POST 而 DELETE 是!
问题:我做错了什么?
路线
Route::resource('animal', 'AnimalController');
CONTROLLER 打印数据表
public function index(Request $request)
{
if($request->ajax()) {
$animals = DB::select('CALL sp_select_animal()');
return DataTables::of($animals)
->addIndexColumn()
->addColumn('action', function($animals){
$actions = '<a href="" class="btn btn-info btn-sm">Edit</a>';
$actions .= '<button type="button" id="'.$animals->id.'" data-name="'.$animals->name.'" name="delete" class="btn btn-danger btn-sm ml-1 delete">Delete</button>';
return $actions;
})
->rawColumns(['action'])
->make(true);
}
return view('animal.index');
}
控制器删除记录
public function destroy($id)
{
$animal = DB::select('CALL sp_destroy_animal(?)', [$id]);
return back();
}
VIEW
jQuery('#BTNdelete').click(function(e){
e.preventDefault();
var url = '{{ route("animal.destroy", ":xxx") }}';
url = url.replace(':xxx', animalID);
jQuery.ajax({
"url": url,
"type": 'DELETE',
"data": {
"_token": "{{ csrf_token() }}"
},
success: function(data) {
setTimeout(function() {
jQuery('#modal').modal('hide');
toastr.warning('The record was successfully deleted', 'Delete Record', {timeOut:3000});
jQuery('#tableAnimal').DataTable().ajax.reload();
}, 100);
}
});
});
现在,如果我创建一个特定的删除记录的路径,一切正常,例如
Route::get('animal/delete/{id}', [AnimalController::class, 'destroy'])->name('animal.destroy')
这将解决问题。但我不想创建额外的路线。我想使用通过 resource()
方法生成的路由。
JavaScript中有很多问题,但问题的根源是浏览器无法发出 DELETE 请求,因此它们必须 fake them。
// bind to the class of the button, not a non-existent ID
jQuery('button.delete').click(function(e) {
// this isn't really needed, a button has no default action
e.preventDefault();
// you do want to stop the event from bubbling though
e.stopPropagation();
// this properly escapes the value for JavaScript, not HTML
var url = @json(route("animal.destroy", ":xxx"));
// WHAT IS animalID ???
url = url.replace(':xxx', animalID);
// build the post request with the fake method added
jQuery.post(
url,
{_token: @json(csrf_token()), _method: "DELETE"},
function(data) {
setTimeout(function() {
jQuery('#modal').modal('hide');
toastr.warning('The record was successfully deleted', 'Delete Record', {timeOut:3000});
jQuery('#tableAnimal').DataTable().ajax.reload();
}, 100);
}
);
});
但必须指出,您的控制器的 index()
方法不应该处理 HTML;那完全是视图的工作。仅向其提供构建 HTML 所需的数据。这可以完成 using column.render
. See 作为示例。
上下文。我在 Laravel 8 工作,我使用 DataTables 插件显示数据库中的记录。正如您将在代码中看到的那样,我创建了所有用于执行 CRUD 的路由:Route::resource('animal', 'AnimalController')。这会为 DESTROY 方法生成一个路径,如下所示:animal/{id}
问题。当我按下特定记录的删除按钮时,记录被删除了,很好,但是浏览器控制台 returns 出现此错误:“此路由不支持 DELETE 方法。支持的方法:GET、HEAD、POST",因此 Javascript 被破坏,记录被删除的警告永远不会显示。如果我将请求类型更改为 POST 而不是 DELETE,错误会告诉我不支持 POST 而 DELETE 是!
问题:我做错了什么?
路线
Route::resource('animal', 'AnimalController');
CONTROLLER 打印数据表
public function index(Request $request)
{
if($request->ajax()) {
$animals = DB::select('CALL sp_select_animal()');
return DataTables::of($animals)
->addIndexColumn()
->addColumn('action', function($animals){
$actions = '<a href="" class="btn btn-info btn-sm">Edit</a>';
$actions .= '<button type="button" id="'.$animals->id.'" data-name="'.$animals->name.'" name="delete" class="btn btn-danger btn-sm ml-1 delete">Delete</button>';
return $actions;
})
->rawColumns(['action'])
->make(true);
}
return view('animal.index');
}
控制器删除记录
public function destroy($id)
{
$animal = DB::select('CALL sp_destroy_animal(?)', [$id]);
return back();
}
VIEW
jQuery('#BTNdelete').click(function(e){
e.preventDefault();
var url = '{{ route("animal.destroy", ":xxx") }}';
url = url.replace(':xxx', animalID);
jQuery.ajax({
"url": url,
"type": 'DELETE',
"data": {
"_token": "{{ csrf_token() }}"
},
success: function(data) {
setTimeout(function() {
jQuery('#modal').modal('hide');
toastr.warning('The record was successfully deleted', 'Delete Record', {timeOut:3000});
jQuery('#tableAnimal').DataTable().ajax.reload();
}, 100);
}
});
});
现在,如果我创建一个特定的删除记录的路径,一切正常,例如
Route::get('animal/delete/{id}', [AnimalController::class, 'destroy'])->name('animal.destroy')
这将解决问题。但我不想创建额外的路线。我想使用通过 resource()
方法生成的路由。
JavaScript中有很多问题,但问题的根源是浏览器无法发出 DELETE 请求,因此它们必须 fake them。
// bind to the class of the button, not a non-existent ID
jQuery('button.delete').click(function(e) {
// this isn't really needed, a button has no default action
e.preventDefault();
// you do want to stop the event from bubbling though
e.stopPropagation();
// this properly escapes the value for JavaScript, not HTML
var url = @json(route("animal.destroy", ":xxx"));
// WHAT IS animalID ???
url = url.replace(':xxx', animalID);
// build the post request with the fake method added
jQuery.post(
url,
{_token: @json(csrf_token()), _method: "DELETE"},
function(data) {
setTimeout(function() {
jQuery('#modal').modal('hide');
toastr.warning('The record was successfully deleted', 'Delete Record', {timeOut:3000});
jQuery('#tableAnimal').DataTable().ajax.reload();
}, 100);
}
);
});
但必须指出,您的控制器的 index()
方法不应该处理 HTML;那完全是视图的工作。仅向其提供构建 HTML 所需的数据。这可以完成 using column.render
. See