带有动态下拉列表的MVC编辑表单-如何设置初始值[重复]

Posted

技术标签:

【中文标题】带有动态下拉列表的MVC编辑表单-如何设置初始值[重复]【英文标题】:MVC Edit form with dynamic dropdown list - How to set initial values [duplicate] 【发布时间】:2018-03-05 03:31:57 【问题描述】:

我正在使用 MVC、C# 和实体框架。 我模型上的对象是:

状态-------- Id , Name

城市 -------- Id , Name , StateId

TheObject----Id、Name、StateId、CityId

我想为 TheObject 创建一个编辑表单。 编辑表单有 2 个动态创建的下拉列表州和城市,城市列表取决于在州列表上所做的选择。 问题是下拉列表填写正确,但是当编辑表单打开时,这两个下拉列表处于空状态,并且没有选择被编辑对象的实际值。

编辑视图的部分代码是这样的:

<div class="form-group">
        @html.LabelFor(u => u.State, new  @class = "control-label col-md-2" )
        <div class="col-md-10">
            @Html.DropDownListFor(u => u.State,
          new SelectList(ViewBag.State, "Id", "Name"),
          "Choose State",
          new  @class = "form-control", @onchange = "selectCities()" )
            @Html.ValidationMessageFor(u => u.State, "", new  @class = "text-danger" )
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(u => u.City, new  @class = "control-label col-md-2" )
        <div class="col-md-10">
            @Html.DropDownListFor(u => u.City,
   new SelectList(Enumerable.Empty<SelectListItem>(), "Id", "Name"),
          "Choose City",
          new  @class = "form-control" )
            @Html.ValidationMessageFor(u => u.City, "", new  @class = "text-danger" )
        </div>
    </div>

function selectCities() 
    debugger;
    var stateId = $("#State").val();
    $.ajax(
        url: '/Home/selectCities',
        type: 'POST',
        datatype: 'application/json',
        contentType: 'application/json',
        data: JSON.stringify( stateId: +stateId ),
        success: function (result) 
            $("#City").html("");
            $("#City").append
            ($('<option></option>').val(null).html("---choose City---"));
            $.each($.parseJSON(result), function (i, cty)
             $("#City").append($('<option></option>').val(cty.Id).html(cty.Name)) )

        ,
        error: function ()  alert("Error !") ,
    );

控制器的部分代码是这样的:

private void Fill_StateDropDownList()
    
        var st = from d in db.States
                  orderby d.Name
                  select d;
        ViewBag.State = st.ToList();
    

  [HttpPost]
    public ActionResult selectCities(string stId)   
      

       List < City > lstcity = new List < City > ();  
        int stateiD = Convert.ToInt32(stId);
        lstgrupet = (from d in db.Citys
                  where d.StateID==stateiD
                 select d).ToList();  
       string result= JsonConvert.SerializeObject(lstgrupet, Formatting.Indented,
       new JsonSerializerSettings  ReferenceLoopHandling = ReferenceLoopHandling.Ignore);
       return Json(result, JsonRequestBehavior.AllowGet);
     

public ActionResult Edit(int? id)
    
        if (id == null)
        
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        
      TheObject obj = db.TheObjects.Find(id);
        if (obj == null)
        
            return HttpNotFound();
        
        Fill_StateDropDownList()            
        return View(obj);
    

    [HttpPost, ActionName("Edit")]
    [ValidateAntiForgeryToken]
    public ActionResult EditPost(int? id)
    
        if (id == null)
        
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        
        var theobjectToUpdate = db.TheObjects.Find(id);

        if (TryUpdateModel(theobjectToUpdate, "",
           new string[]  "Name","StateId","CityId" ))
        
                try
                
                    db.SaveChanges();
                    return RedirectToAction("Index");
                
                catch (Exception)
                
                    ModelState.AddModelError("", "Error.");
                

        
        Fill_StateDropDownList()
        return View(theobjectToUpdate);
    

【问题讨论】:

【参考方案1】:

实际上SelectList 有一个带有一个名为selectedValue 的参数的构造

现在你应该知道该怎么做了

在编辑视图中

<div class="form-group">
    @Html.LabelFor(u => u.State, new  @class = "control-label col-md-2" )
    <div class="col-md-10">
        @Html.DropDownListFor(u => u.State,
      new SelectList(ViewBag.State, "Id", "Name", Model.State),
      "Choose State",
      new  @class = "form-control", @onchange = "selectCities()" )
        @Html.ValidationMessageFor(u => u.State, "", new  @class = "text-danger" )
    </div>
</div>

【讨论】:

不起作用,State 和 City 下拉列表仍处于空状态,因此未选择当前编辑对象的值。 @Adriano - 您必须使用所选值填充 u.State。 @Erik 你能告诉我我该怎么做吗? 您将 Id 存储在 Model.State 中还是存储了对象?如果是对象,请尝试 Model.State.Id。无论如何,为参数分配一个值,该值可以在 select 的选项值中找到 @Ray 我这样用过.... Model.StateID ,但不起作用。【参考方案2】:

您已经拥有保存的州和城市值。您所要做的就是根据保存的州 ID 加载城市子集,并使用该集合来呈现城市的下拉列表

只要视图模型的 City 属性值与选项的 value 属性值之一匹配,DropDownListFor 辅助方法就会从 SELECT 元素中选择相应的选项。

public ActionResult Edit(int? id)

    if (id == null)
    
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    
    TheObject obj = db.TheObjects.Find(id);
    if (user == null)
    
        return HttpNotFound();
    
    Fill_StateDropDownList() 
    FillCities(obj.State);           
    return View(obj);

private void FillCities(int stateId)

   ViewBag.CityList = db.Cities
                       .Where(g => g.StateId== stateId)
                       .Select(f => new SelectListItem()  
                                                            Value = f.Id.ToString(), 
                                                            Text = f.Name )
                       .ToList();

调整视图

var cityList = new List<SelectListItem>();
if (ViewBag.CityList != null)

    cityList =ViewBag.CityList as List<SelectListItem>;

@Html.DropDownListFor(u => u.City, cityList , "Choose City")

另一个选项是在页面加载时进行 ajax 调用(文档准备好根据 state 下拉列表的值获取城市)。如果您有多个嵌套的下拉菜单,它会变得复杂。(最终陷入回调地狱)

【讨论】:

评论不适用于扩展讨论或调试会话;这个对话是moved to chat。请确保将聊天中的相关信息重新合并到问题或答案中(视情况而定)。

以上是关于带有动态下拉列表的MVC编辑表单-如何设置初始值[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有逗号分隔值的单元格通过apps脚本创建动态下拉列表

关于bootstrap 表单 带有多选下拉列表和kkpager翻页 的传值问题

Django从当前实例设置初始下拉值?

MVC 5下拉列表用于编辑视图中的多选值绑定

Angular 2 - 如何使用下拉列表的值生成表单?

动态添加部分视图后如何重新初始化JQuery