【问题标题】:Passing JS variable(array) to Laravel Controller将 JS 变量(数组)传递给 Laravel 控制器
【发布时间】:2021-12-30 03:30:44
【问题描述】:

我有一个使用 JS 和 Laravel 的项目。

在blade.php 中,我有一个带有复选框的项目列表,我根据其状态从外部数据库中检索到该列表。我需要能够选择一些项目并通过单击更改其状态(例如“存档”)。

  function getSelected(){
  let selected = new Array()
  let tblTickets = document.getElementById('tblTickets')
  let checked = tblTickets.getElementsByTagName("input")
  for (let i = 0; i < checked.length; i++) {
    if (checked[i].checked) {
        selected.push(checked[i].value)
    }
 }
  if (selected.length > 0) {
   let nr = selected.map(Number)
    console.log(nr)

 }
}

这是我的 JS 代码,它为我提供了数字数组(id(s)- 所选项目的主键)

在 web.php 中,我为更新创建了命名路由:

Route::put("/tickets/update", [TicketsController::class, 'update'])->name('tickets.update');

在门票控制器中,我有以下功能:

public function update($ids){
    foreach ($ids as $id) {
        $tickets = DB::connection('secondDB')->table('ticket')
            ->join('ticket_status', 'id', '=', 'status_id')
            ->where('id', '=', $id)
            ->update(['name' => 'Closed']);
    }
     $route= route('tickets.update');
    return view('tickets', [
        'tickets' => $tickets, 
        'route' => $route

}

(它第二个连接的外部数据库,所以我无法为它制作模型,所以我手动白查询)

在tickets.blade 中我添加了脚本,这样我就可以在JS 中访问路由变量

 <script>
  const ticketsApi = @json($route);
 </script>

我的问题是 - 如何使用我在 Blade.php 中传递的路由将一组已检查票证的 ids 发布到控制器中的“更新”函数? (我知道我也可以在 JS 中循环,但如果我有 1000 个票证,我需要 POST 1000 个请求,我发现在 PHP 中循环更有效)。

这个不行

 fetch(route,
    {
        method: "POST",
        body: JSON.stringify(numbers)
    })
    .then(res => res.json())
    .catch(error => {
        console.error('Error:', error);

    })
    .then(data => {
        console.log(JSON.stringify(data));
    });

感谢您的任何提示。

更新:

js函数:

function getSelected(){
let payload = new Array()
let tblTickets = document.getElementById('tblTickets')
let checked = tblTickets.getElementsByTagName("input")
for (let i = 0; i < checked.length; i++) {
    if (checked[i].checked) {
        payload.push(checked[i].value)
    }
}
let numbers = []
if (payload.length > 0) {
    numbers = payload.map(Number)
    console.log(numbers)
}

const putMethod = {
    method : 'PUT',
    headers: {
        'Content-type': 'application/json; charset=UTF-8'
    },
    body: JSON.stringify(numbers)
}
fetch(urlUpdate, putMethod)
    .then(res => res.json())
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error('Error:', error);

    })

}

web.php:

Route::put("/tickets/update", [TicketsController::class, 'update'])->name('tickets.update');

控制器:

 public function update(Request $request): \Illuminate\Http\JsonResponse
{
    $request->validate([
        'ids' => ['required', 'array', 'min:1'],
        'ids.*' => ['integer']
    ]);
        $tickets = DB::connection('secondDb')->table('ticket')
            ->join('ticket_status', 'id', '=', 'status_id')
            ->whereIn('id', $request->input('ids'))
            ->update(['name' => 'Closed ']);


    return response()->json([
        'ticketsUpdated' => $tickets
    ]);

}

我仍然收到两个错误: action.js:57 PUT http://mypath/tickets/update 419(未知状态) action.js:63 错误:SyntaxError: Unexpected token

我真的不知道如何传递我的数组,将其拆分为数字作为 id 并更新数据库。我有一个内部数据库的内置更新路线。但是对于外部我不能使用 safe() 并且内置函数在路由 /bills/{id} 中提供了一个 id,但我想更新一堆,而不是一个一个

【问题讨论】:

  • 不应该是 fetch 方法,而是 PUT,因为这是您在路由文件中定义的?此外,仅供参考,您可以使用on() 为模型指定连接,例如Model::on('secondDB'),甚至创建一个新模型和set the connection explicitly
  • 是的,我的错。我只是在玩 POST 和 PUT。它绝对应该是 PUT。但是,我与 DB 的连接很好。我可以在控制台中获取 GET 数据。但是PUT有问题。 PHP控制器中的返回状态会出错吗?我认为定义 API 调用的控制器函数有问题,但无法弄清楚到底是什么
  • const putMethod = { method : 'PUT', headers: { 'Content-type': 'application/json; charset=UTF-8' }, body: JSON.stringify(numbers) } fetch(urlUpdate, putMethod) .then(res => res.json()) .then(data => { console.log(data); } ) .catch(error => { console.error('Error:', error); }) 我有这个更新。但它在控制台 action.js:57 PUT myRoute/update 419 (unknown status) 中给了我一个错误
  • 您正在将 id 添加到请求的正文中,但您没有从控制器中的请求中检索它们。我无法从您的代码中看出,但您似乎也没有为 id 提供密钥,以便您也可以从控制器中的请求中检索它们。

标签: javascript php laravel


【解决方案1】:

首先,您在获取请求中使用POST 方法,而您的路由使用PUT 动词。 因此,您必须将 fetch 中指定的方法更改为 PUT

以下是您的控制器的一些问题:

  1. 您的 id 数组在您的请求正文中,而不是作为 URL 的参数,因此您需要调整控制器操作以使用请求。

  2. 您想使用带有 id 列表的路由来避免对数据库进行 1000 次查询,但您正在这样做,因为您使用的是 foreach 并且它没有经过优化。您可以改用whereIn()

  3. 知道您正在使用 fetch,因此更愿意返回 JSON 响应而不是视图。

这是一个代码示例:

public function update(Request $request)
{
    $request->validate([
        'ids' => ['required', 'array', 'min:1'],
        'ids.*' => ['integer']
    ]);

    $tickets = DB::connection('secondDB')->table('ticket')
            ->join('ticket_status', 'id', '=', 'status_id')
            ->whereIn('id', $request->input('ids'))
            ->update(['name' => 'Closed']);

    return response()->json([
      'ticketsUpdated' => $tickets;
    ]);
}

【讨论】:

  • @Natalia 如果我的回答对你有帮助,请点赞。请记住验证您的请求,如我所展示的,尤其是使用 whereIn 来大幅限制对数据库的查询数量。
【解决方案2】:

谢谢大家。我找到了解决方案,让它在没有 JS 的情况下仅 Laravel 工作

在刀片中:

 <form action="/tickets/update" method="POST">
 @csrf
 @method('PUT')

 @foreach($tickets as $ticket)

                <tr>
                    <td>
                        <input class="check" type="checkbox" id="{{$ticket->ticket_id}}" value="{{$ticket->ticket_id}}" name="ids[]" >
                    </td>

在控制器中:

 public function update(Request $request)
{
    $numbers = $request->input('ids');
    foreach ($numbers as $number)
    {
        $tickets = DB::connection('osdtbs')->table('ticket')
            ->where('ticket_id', '=', $number)
            ->update(['status_id' => '7']);
    }


    return redirect('/tickets');

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-06
    • 2015-01-06
    • 2015-11-02
    • 2014-08-29
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 2014-08-01
    相关资源
    最近更新 更多