使用AJAX MVC 4填充的DropDownListAJAX、MVC、DropDownList

2023-09-10 20:21:52 作者:こ 不负如来不负卿

我已经制定了查看包含2 @ DropDownListFor的助手:

  @using(Html.BeginForm(CreateOneWayTrip,旅行))
    {
        @ Html.ValidationSummary(假);
        <字段集>
            <传奇>输入您的旅行详情及LT; /传说>

            <标签>开始点< /标签>
            @ Html.DropDownListFor(M => m.StartPointProvince,(SelectList的)ViewBag.Provinces,新{@Id =province_dll,@class =表单控制})
            @ Html.DropDownListFor(M => m.StartPointCity,(SelectList的)ViewBag.Cities,新{@Id =city_dll,@class =表单控制})

            < P类=浮动:无;文本对齐:中心;>
                <按钮类型=提交值=创建级=BTN BTN-信息BTN-圈BTN-LG>
                    <我类=发发检查>< / I>
                < /按钮>

                <按钮类型=提交值=创建级=BTN BTN-警告BTN-圈BTN-LG>
                    <我类=发发次>< / I>
                < /按钮>
            &所述; / P>
        < /字段集>
    }
 

下面是我用来捕获数据的临时模型:

 公共类CaptureCreateTrip
 {
    [需要]
    [显示(NAME =线路编号)
    公共字符串TRIPID {获得;组; }

    [需要]
    公共字符串StartPointProvince {获得;组; }

    [需要]
    公共字符串StartPointCity {获得;组; }
}
 

一个创建页和第二将基于该用户选择在第一个DropDownList选项进行填充时的填充的DropsDownList的。要做到这一点,我使用AJAX。在JavaScript来我用的是这样的:

$(#province_dll)。改变(函数(){         $阿贾克斯({             网址:getCities /车次,             类型:'后',             数据: {                 provinceId:$(#province_dll)VAL()。             }         })。完成(功能(响应){             $(cities_dll)HTML(响应);         });     }); ajax url 请求发送不到spring mvc controller

下面是AJAX调用控制器:

  [HttpPost]
  公众的ActionResult getCicites(INT provinceId)
  {
      VAR lstCities =新的SelectList(新[] {City1,城2,City3});

      返回内容(的string.join(,lstCities));
  }
 

直到此时一切正常 - 当我选择在我的省下拉列表中值的JavaScript事件触发和控制操作不会返回的选择列表值到城市下拉列表中,但问题是,该数据(formatof的数据),该操作将返回不正确。我测试通过创建一个段落元素和更新它的文字与Ajax调用,这是的返回值: "System.Web.Mvc.SelectListItemSystem.Web.Mvc.SelectListItemSystem.Web.Mvc.Select‌​‌​ListItem"

*注:我是新来的Ajax和学习jQuery和AJAX的过程

。 解决方案

你得到的字符串的总汇原因System.Web.Mvc.SelectListItemSystem VAR lstCities =新的SelectList(新[] {City1,城2,City3}); 返回的IEnumerable< SelectListItem> 的string.join(,lstCities)要求每个的ToString()方法 SelectListItem 返回System.Web.Mvc.SelectListItemSystem的(不是值文本属性 SelectListItem

填充第二个下拉列表中选择最好的方法是返回一个包含城市的集合JSON和更新了ajax成功回调DOM。有没有必要创建一个的SelectList - 它只是不必要的额外开销,你回来至少3倍的数据返回给客户端是必要的(客户端没有概念一个C# SelectListItem 类。

 公共JsonResult FetchCities(INT provinceId)//它的一个GET,而不是一个POST
{
    //在现实中,你会做一个数据库查询的基础上provinceId的价值,但是基于code,你已经证明
    VAR城市=新的名单,其中,串>(){City1,城2,City3});
    返回JSON(市,JsonRequestBehavior.AllowGet);
}
 

然后在脚本(不知道为什么你已经修改了默认 ID ID =StartPointProvince ID =province_dll,但)

  VAR URL ='@ Url.Action(FetchCities,旅行); //不要硬code你的网址!
VAR城市= $('#city_dll'); //缓存它
$(#province_dll)。改变(函数(){
    VAR ID = $(本).VAL(); //使用$(本),这样你就不会再遍历DOM
    $ .getJSON(URL,{provinceId:ID},功能(响应){
        cities.empty(); //删除任何现有选项
        $每个(响应函数(指数,项目){
            cities.append($('< /选项>)文本(项目)。);
        });
    });
});
 

修改

继OP的评论,如果数据库包含的表名城市与田 ID 名称,那么控制器的方法是像

 公共JsonResult FetchCities(INT provinceId)//它的一个GET,而不是一个POST
{
    VAR城市= db.Cities.Select(C =>新建
    {
      ID = c.ID,
      文字= c.Text
    }
    返回JSON(市,JsonRequestBehavior.AllowGet);
}
 

和脚本来创建选项是

  $。每一个(响应函数(指数,项目){//产品目前包含的属性ID和文本对象
    cities.append($('< /选项>)文本(item.Text).VAL(item.ID)。);
});
 

I have a view in place that contains 2 @DropDownListFor's Helpers:

    @using (Html.BeginForm("CreateOneWayTrip", "Trips"))
    {
        @Html.ValidationSummary(false);
        <fieldset>
            <legend>Enter Your Trip Details</legend>

            <label>Start Point</label>
            @Html.DropDownListFor(m => m.StartPointProvince, (SelectList)ViewBag.Provinces, new { @Id = "province_dll", @class = "form-control" })
            @Html.DropDownListFor(m => m.StartPointCity, (SelectList)ViewBag.Cities, new { @Id = "city_dll", @class = "form-control" })

            <p style="float: none; text-align: center;">
                <button type="submit" value="Create" class="btn btn-info btn-circle btn-lg">
                    <i class="fa fa-check"></i>
                </button>

                <button type="submit" value="Create" class="btn btn-warning btn-circle btn-lg">
                    <i class="fa fa-times"></i>
                </button>
            </p>
        </fieldset>
    }

Here is the temporary model I use to Capture data:

 public class CaptureCreateTrip
 {
    [Required]
    [Display(Name = "Trip ID")]
    public string TripID { get; set; }

    [Required]
    public string StartPointProvince { get; set; }

    [Required]
    public string StartPointCity { get; set; }
}

One of the DropsDownList's are populated when the page is created and the second will be populated based on the option that the user chooses in the first DropDownList. To achieve this, i am using ajax. The javascript to I use looks like this:

$("#province_dll").change(function () {
        $.ajax({
            url: 'getCities/Trips',
            type: 'post',
            data: {
                provinceId: $("#province_dll").val()
            }
        }).done(function (response) {
            $("cities_dll").html(response);
        });
    });

Here is the Controller the AJAX calls:

  [HttpPost]
  public ActionResult getCicites(int provinceId)
  {
      var lstCities = new SelectList(new[] { "City1", "City2", "City3" });

      return Content(String.Join("", lstCities));
  }

Up until this point everything works - When I choose a value in my Province DropDown the javascript event fires and the Controller action does return the select list values to the Cities DropDown, the problem however is that the data(of the formatof the data) that the Action returns is incorrect. I Tested this by creating a Paragraph element and updating it's text with the return value of the ajax call, which is : "System.Web.Mvc.SelectListItemSystem.Web.Mvc.SelectListItemSystem.Web.Mvc.Select‌​‌​ListItem"

*Note: I am new to ajax and in the process of learning Jquery and AJAX.

解决方案

The reason you are getting a colletion of strings "System.Web.Mvc.SelectListItemSystem" is that var lstCities = new SelectList(new[] { "City1", "City2", "City3" }); returns IEnumerable<SelectListItem> and String.Join("", lstCities) calls the .ToString() method of each SelectListItem item in the collection which returns "System.Web.Mvc.SelectListItemSystem" (not the value of the Text property of SelectListItem)

The best way to populate the second dropdown list is to return json containing the collection of cities and update the DOM in the ajax success callback. There is no reason to create a SelectList - its just unnecessary extra overhead and you returning at least 3 times as much data back to the client as is necessary (the client has no concept of a C# SelectListItem class.

public JsonResult FetchCities(int provinceId) // its a GET, not a POST
{
    // In reality you will do a database query based on the value of provinceId, but based on the code you have shown
    var cities = new List<string>() { "City1", "City2", "City3" });
    return Json(cities, JsonRequestBehavior.AllowGet);
}

Then in the script (not sure why you have modified the default id from id="StartPointProvince" to id="province_dll", but)

var url = '@Url.Action("FetchCities", "Trips")'; // Don't hard code your url's!
var cities = $('#city_dll'); // cache it
$("#province_dll").change(function () {
    var id = $(this).val(); // Use $(this) so you don't traverse the DOM again
    $.getJSON(url, { provinceId: id }, function(response) {
        cities.empty(); // remove any existing options
        $.each(response, function(index, item) {
            cities.append($('</option>').text(item));
        });
    });
});

Edit

Further to OP's comments, if the database contained a table name Cities with fields ID and Name, then the controller method would be something like

public JsonResult FetchCities(int provinceId) // its a GET, not a POST
{
    var cities = db.Cities.Select(c => new
    {
      ID = c.ID,
      Text = c.Text
    }
    return Json(cities, JsonRequestBehavior.AllowGet);
}

and the script to create the options would be

$.each(response, function(index, item) { // item is now an object containing properties ID and Text
    cities.append($('</option>').text(item.Text).val(item.ID));
});