【问题标题】:How to retrieve search result data objects from view to controller如何从视图检索搜索结果数据对象到控制器
【发布时间】:2020-07-20 12:29:13
【问题描述】:

我正在使用 Laravel 6,并且正在开发一个仅用于搜索大表的应用程序。

我创建了不同的函数来按距离排序(地理位置、给定地址或简单的区域选择),到目前为止,我使用 Model::all(); 进行了测试,它们运行良好。

我在我的模型上添加了一个搜索过滤器,它可以工作。

问题是:我想在 $filteredResults 之类的数据中检索结果,然后使用具有相同 $filteredResults 的不同函数。

我希望用户能够通过不同的按钮/功能对搜索结果进行排序。

如何从视图中检索到作为对象数据的搜索结果到控制器。

我的观点(例如,只放一个按钮,我不会用几个按钮来进行距离排序):

<!-- FILTER FORM -->    
<form method="POST" action="/events/search" class="w-50">
    @csrf
    <input name="Nom" id="Nom" type="text" class="form-control" placeholder="Nom de l'évènement" />
    <input type="text" class="form-control" placeholder="Type d'évènement" id="Type" name="Type" />
    <input name="lieu" id="lieu" type="text" placeholder="Lieu de l'évènement" class="form-control" />
    <button class="btn btn-outline-secondary" type="submit">Filtrer</button>
</form>

<!-- SORTING METHODS -->
<!-- AROUND ME -->
<!-- BY ADDRESS -->
<!-- BY AREA / ZONE -->
<a class="stpierre" href="/events/St-Pierre">Saint-Pierre</a>

<!-- TABLE DISPLAYING EVENTS --> 
<table class="table table-bordered table-striped">
    <thead class="text-center thead-dark">
        <tr>
            <th scope="col">ID</th>
            <th scope="col">Nom</th>
            <th scope="col">Thématique</th>
            <th scope="col">Lieu</th>
            <th scope="col">Type</th>
            <th scope="col">Programme</th>
            <th scope="col">Objectif</th>
        </tr>
    </thead>
    <tbody>
    @foreach($events as $produit)
        <tr>
            <th scope="row">{{ $produit -> idNosEvenements}}</th>
            <td>{{ $produit -> Nom}} </td>
            <td>{{ $produit -> idThematiques }}</td>
            <td>{{ $produit -> lieu }}</td>
            <td>{{ $produit -> Type }}</td>
            <td class="text-center"> {{ $produit -> Programme }} </td>
            <td class="text-center"> {{ $produit -> Objectifs }} </td>                       
        </tr>
    @endforeach
    </tbody>
</table>

我的路线:

// EVENTS
Route::get('/events', 'MesEventsController@index'); // retrieve all events
Route::post('/events/a-proximite', 'MesEventsController@distGeoLoc'); // sort all events near user
Route::post('/events/search', 'MesEventsController@searchEvents'); // filter search for events
Route::get('/events/{zone}', 'MesEventsController@distZone'); // sort all events by area
Route::get('/test/geocode', 'MesEventsController@distGeocode'); // sort all events by geocoding address

我的控制器:

public function index() {
    $events = Nosevenement::all();
    return view('events', ['events' => $events]);
}

// SORTING METHODS WITH EVENTS:all() FOR TESTING PURPOSES
// SORTING EVENTS BY AREA / ZONE
public function distZone($zone) {
    switch($zone) {
    case "St-Pierre":
        $latitude = -21.3328174;
        $longitude = 55.4630668;
        break;
    case "St-Paul":
        $latitude = -21.0140263;
        $longitude = 55.2607508;
        break;
    default:
        $latitude = -20.8926767;
        $longitude = 55.4827193;
        break;
    }
    $query = Nosevenement::distance($latitude, $longitude);
    $asc = $query -> orderBy('distance', 'ASC') -> get();
    return view('events', ['events' => $asc], ['zone' => $zone]);
}

我尝试对搜索结果进行序列化()并将它们放入隐藏的输入中,然后检索并取消序列化()它们,但出现错误:

public function distZone($zone, Request $request) {
    // dd($zone, $request);
    if(!empty($request)) {
        $query = unserialize($request);
    }
    switch ($zone) { etc }

unserialize(): 在 19097 个字节的偏移量 0 处出错

所以我认为搜索结果太大了。 我可能想只检索搜索结果 $id ?

我认为我目前对此没有足够的看法,如果您有任何想法将不胜感激:)

【问题讨论】:

    标签: javascript php jquery laravel search


    【解决方案1】:

    您的问题只是关于排序,对吧?不做更精确的过滤?

    如果你想序列化你的请求参数,你必须使用-&gt;all()(将所有参数导出到数组):

    // Serialize parameters to append them into hidden input
    // <input type="hidden" name="s" value="{{ $s }}">
    $s = serialize($request->all());
    
    // Unserialize after
    $params = unserialize($request->s);
    

    如果您只想进行排序,您可以直接在视图中使用 Javascript 轻松完成。它会更高效,并且不会使简单排序任务的服务器过载。

    我建议您在客户端使用 jQuery。您可以将坐标附加为行的数据属性:

    <a class="stpierre" href="javascript:sortDistZone(-21.3328174, 55.4630668)">Saint-Pierre</a>
    
    <table id="results" class="table table-bordered table-striped">
        <thead class="text-center thead-dark">
            <tr>
                <th scope="col">ID</th>
                <th scope="col">Nom</th>
                <th scope="col">Thématique</th>
                <th scope="col">Lieu</th>
                <th scope="col">Type</th>
                <th scope="col">Programme</th>
                <th scope="col">Objectif</th>
            </tr>
        </thead>
        <tbody>
        @foreach($events as $produit)
            <tr data-lat="{{ $produit->latitude }}" data-lon="{{ $produit->longitude }}">
                <th scope="row">{{ $produit -> idNosEvenements}}</th>
                <td>{{ $produit -> Nom}} </td>
                <td>{{ $produit -> idThematiques }}</td>
                <td>{{ $produit -> lieu }}</td>
                <td>{{ $produit -> Type }}</td>
                <td class="text-center"> {{ $produit -> Programme }} </td>
                <td class="text-center"> {{ $produit -> Objectifs }} </td>                       
            </tr>
        @endforeach
        </tbody>
    </table>
    
    <script type="text/javascript">
    distance(lat1, lon1, lat2, lon2) {
        return ... your distance function here ...;
    }
    
    sortDistZone(latitude, longitude) {
        // A simple compare function, used by the sort below
        const compare_rows = function (a, b) {
            const a_lat = $(a).data('lat');
            const a_lon = $(a).data('lon');
            const a_distance = distance(a_lat, a_lon, latitude, longitude);
    
            const b_lat = $(b).data('lat');
            const b_lon = $(b).data('lon');
            const b_distance = distance(a_lat, a_lon, latitude, longitude);
    
            if (a_distance>b_distance){
                return 1;
            }
            if (a_distance<b_distance){
                return -1;
            }
            return 0;
        };
    
        // the actual sort
        $('#results tr').sort(compare_rows).appendTo('#results tbody');
    }
    </script>
    

    鼓起勇气!! :)

    【讨论】:

    • 感谢您的回答皮埃尔!我确实尝试了隐藏输入和序列化(对不起,我忘了更新我的代码)但是反序列化给了我一个错误。当我dd($request -&gt; results); 时,我得到一个包含所有数据的非常大的字符串,但是 unserialize 给我一个错误。对于 jQuery 排序,我承认我没有考虑过。我会试一试。特别是因为我做 3/4 的距离排序,通过脚本检索数据。等等! :)
    【解决方案2】:

    我终于让它在后端和前端工作(后端用于另一个项目)。

    但是对于前端,我不得不做一些调整,因为我遇到了很多问题。

    最后,我遍历所有行以计算每个事件的距离,然后将其传递给 HTML 中的数据属性。

    然后使用 data 属性进行排序,并从那里将行附加到正文。

    $('#results tbody tr').each(function() {
        const a_lat = $(this).data('lat');
        const a_lon = $(this).data('lon');
        var a_distance = distance(a_lat, a_lon, latitude, longitude, 'K');
        $(this).attr("data-madist", a_distance);
        console.log(Math.round(a_distance) + "km entre l'évènement et " + zone);
    });
    
    const compare_rows = function (a, b) {
        return a.getAttribute('data-madist') - b.getAttribute('data-madist');
    };
    
    // Calls the comparison function and then adds the results to the body
    $('#results > tbody > .sortable').sort(compare_rows).appendTo('#results tbody');
    

    再次感谢 JS 示例 ;)

    【讨论】:

      猜你喜欢
      • 2016-05-12
      • 2017-08-12
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-25
      • 1970-01-01
      • 2014-06-17
      相关资源
      最近更新 更多