通过Ajax对选择框动态依赖于Laravel,但如何通过不同的表获取数据,怎么办?

时间:2018-11-14 17:40:54

标签: javascript php mysql ajax laravel

我试图以 Country-> State-> Municipality 的方式,使一组3个选择框的形式与上述选择框相关。

我关注的是this tutorial,它成功获取了数据并填充了第一个选择框(在本例中为Country)。

问题在于,在该教程中数据位于单个表中,而在我的应用程序中,数据位于多个表中。

我想知道如何在与上述选择框中的所选项目的ID相对应的多个表中获取数据?但是以LARAVEL的方式吗?

我的HTML(全部基于上面链接的教程):

 {{-- Muestra los estados sacados de la base de datos. --}}
                        <div id="inputs-estado">
                            <div class="form-group">
                                {{-- Estados --}}
                                <label for="">Estado</label>
                                <select name="state" id="state" class="form-control dynamic" data-dependant="state">
                                    @foreach ($estados as $estado)
                                    <option value="{{ $estado->state }}">{{ $estado->state }}</option>
                                    @endforeach
                                </select>
                                <br>
                                {{-- Municipio/Delegación --}}
                                <label for="">Ciudad</label>
                                <select name="state" id="state" class="form-control dynamic" data-dependant="city">
                                    <option value="">Selecciona la ciudad</option>
                                </select>
                                <br>
                                {{-- Colonia --}}
                                <label for="">Municipo</label>
                                <select name="state" id="state" class="form-control dynamic" data-dependant="municipality">
                                    <option value="">Selecciona el municipio</option>
                                </select>

                            </div>
                        </div>

JS:

formDynamic.change(function () {
    if ($(this).val() != '') {
        let select = $(this).attr('id');
        let value = $(this).val();
        let dependent = $(this).data('dependent');
        let _token = $('input[name="_token"]').val();

        $.ajax({
            url: "{{ route('postscontroller.fetch') }}",
            method: "POST",
            data: {
                select: select,
                value: value,
                _token: _token,
                dependent: dependent
            },
            success: function (result) {
                $('#' + dependent).html(result);
            }
        })
    }
});

控制器:

public function create()
{

    // Toma los estados de la base de datos.
    $estados = DB::connection('db_postalcodes')
        ->table('state')
        ->groupBy('state')
        ->get();

    // El with hace que se adjunten variables al view.
    return view('admin.posts.create')->with('estados', $estados);
}

public function fetch(Request $request)
{
    $state_id = DB::connection('db_postalcodes')->table('city')->get();
    $select = $request->get('select');
    $value = $request->get('value');
    $dependent = $request->get('dependent');
    $data = DB::connection('db_postalcodes')
        ->table('city')
        ->where($select, $state_id->state_id)
        ->groupBy($dependent)
        ->get();

        $output = '<option value="">Select '.ucfirst($dependent).'</option>';

        foreach($data as $row){
            $output .= '<option value="'.$row->$dependent.'">'.$row->$dependent.'</option>';
        }

        echo $output;
}

Routes.php

Route::group(['prefix' => 'admin', 'namespace' => 'Admin', 'middleware' => 'auth'], function () {

    Route::get('/', 'AdminController@index')->name('admin');    
    Route::get('posts', 'PostsController@index')->name('admin.posts.index');
    Route::get('posts/create', 'PostsController@create')->name('admin.posts.create');
    Route::post('posts/create', 'PostsController@fetch')->name('postscontroller.fetch');
    Route::post('posts', 'PostsController@store')->name('admin.posts.store');
});

我的桌子:

enter image description here

1 个答案:

答案 0 :(得分:1)

Laravel的模型和关系在这里可以提供很大帮助。特别是hasManyThrough。请查看Docs,以获取更多详细说明。

您将需要三个模型:国家/地区,州和城市。您可以使用工匠通过php artisan make:model modelName进行制作,也可以在您的项目中手动创建它们。无论哪种方式,它都应如下所示:

国家型号

use Illuminate\Database\Eloquent\Model;

class Country extends Model {

  // A Country can have many Municipalities but they do not directly belong
  // to the Country they belong to the State -- Which belongs to the Country
  public function municipalities() {
    return $this->hasManyThrough('App\Municipality', 'App\State');
  }

  // Each Country can have many States
  public function states() {
    return $this->hasMany('App\State');
  }

}

状态模型

use Illuminate\Database\Eloquent\Model;

class State extends Model {

  // Assuming each State can only belong to One Country
  public function country() {
    return $this->belongsTo('App\Country');
  }

  // Each State can have many Municipalities
  public function municipalities() {
    return $this->hasMany('App\Municipalities');
  }

}

市政模型

use Illuminate\Database\Eloquent\Model;

class Municipality extends Model {

  // Assuming each Municipality can belong to only one State
  public function state() {
    return $this->belongsTo('App\State');
  }

  // Should you ever need this Municipality's Country
  public function country() {
    return $this->state->country;
  }

}

所有这些工作都基于您具有类似于以下内容的表结构:

国家/地区:

| id | name | another_column |
-----------------------------
  1  | USA  |

状态:

| id | country_id | name | another_col |
----------------------------------------
  1  |      1     |  OK  |

市镇

| id | state_id | postalcode_id | name | another_col |
------------------------------------------------------
  1  |    1     |       1       | OKC  |

邮政编码:

| id | state_id | postal_code |
-------------------------------
  1  |     1    |   73102     |

对于控制器,您可以将其分为3个端点:getCountriesgetStatesByCountrygetCitiesByState-每个端点都基于传递给它的ID来获取数据。

public function getCountries(Request $request) {
  $id = $request->get('id');
  if ( $id ) {
    // Or return some string you want to return
    return response()->json(Country::find($id));
  }
  $countries = Country::all();
  // or loop over all $countries and make a string
  return response()->json($countries);
}

public function getStatesByCountry(Request $request) {
  $id = $request->get('country_id');
  return response()->json(Country::find($id)->states);
  // Or
  // return response()->json(State::where('country_id', '=', $id)->get());
}

public function getCitiesByState(Request $request) {
  $id = $request->get('state_id');
  return response()->json(State::find($id)->municipalities);
  // or return response()->json(Municipality::where('state_id', '=', $id)->get());
}

每次更改动态选项之一时,您都要求降低一级。因此,如果您更改国家/地区,则将请求getStatesByCountry-如果州/州更改,则将请求getCitiesByState

最后,如果您想按国家/地区访问所有城市

public function getCitiesByCountry(Request $request) {
  $id = $request->get('country_id');
  return response()->json(Country::find($id)->municipalities);
}

编辑

您将把每个这些功能放在控制器中以处理请求。您还需要更新路由web.php,并为每个函数添加路由和处理程序。

// {id?} signifies an optional parameter. Based on the func. passing
// no ID gets all Countries - specifying one only gets the one.
Route::get('/posts/get-countries/{id?}', 'PostController@getCountries');
Route::get('/posts/get-states-by-country/{id}', 'PostController@getStatesByCountry');
Route::get('/posts/get-cities-by-state/{id}', 'PostController@getCitiesByState');