希望有人能看到如何解决这个问题,因为我已经尝试了所有我能想到的东西。当我的MVC5应用程序中的创建()视图加载时,我首先在我的控制器(例如)中填充多个[SelectList(...)]
:
ViewBag.Model_Id = new SelectList(db.DBT_MODELS.OrderBy(x => x.MODEL_DESCRIPTION), "MODEL_ID", "MODEL_DESCRIPTION");
然后我在创建()视图中使用此[SelectList(...)]
填充Html.DropDownListFor(...)
:
<div class="form-group">
<span class="control-label col-md-2">Model:</span>
<div class="col-md-4">
@Html.DropDownListFor(model => model.MODEL_ID, (SelectList)ViewBag.Model_Id, htmlAttributes: new { @class = "form-control dropdown", @id = "selectModel" })
@Html.ValidationMessageFor(model => model.MODEL_ID, "", new { @class = "text-danger" })
</div>
<div class="col-md-2">
<div class="btn-group">
<button id="createNewModel" type="button" class="btn btn-success" aria-expanded="false">CREATE NEW</button>
</div>
</div>
<div class="col-md-4">
<div id="createModelFormContainer" style="display:none">
<form action="/createNewModel">
<input type="text" id="textNewModel" name="model_description" placeholder="New Model" />
<input type="button" id="submitNewModel" value="Submit" />
<input type="button" id="cancelNewModel" value="Cancel" />
</form>
</div>
</div>
</div>
很简单,这一切都按预期工作。问题在于我试图融入的一些扩展功能。我的主要类有几个属性,基本上是我的数据库中的外键。当用户进入我的主模型中的Create/Edit()
实体时,我希望允许他们能够向这些外表中添加新实体,而无需离开当前View
。
因此,我添加了(对于每个外国财产,使用(模型)作为示例)上面显示的代码,并在下面再次使用按钮显示/隐藏小表单,以便用户插入新值并拥有它添加到DropDownList:
<div class="col-md-2">
<div class="btn-group">
<button id="createNewModel" type="button" class="btn btn-success" aria-expanded="false">CREATE NEW</button>
</div>
</div>
<div class="col-md-4">
<div id="createModelFormContainer" style="display:none">
<form action="/createNewModel">
<input type="text" id="textNewModel" name="model_description" placeholder="New Model" />
<input type="button" id="submitNewModel" value="Submit" />
<input type="button" id="cancelNewModel" value="Cancel" />
</form>
</div>
</div>
我的submitNewModel()
点击事件获取用户输入的新值,然后使用对控制器方法的JSON调用将其添加到数据库表中。然后返回这个新值(以及它的新ID),重置DropDownList的表单,并将DropDownList的当前值设置为新添加的值:
$('#createNewModel').click(function () {
$('#createModelFormContainer').show();
})
$('#cancelNewModel').click(function () {
$('#createModelFormContainer').hide();
})
$('#submitNewModel').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewModel').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '@Url.Action("createNewModel", "INV_ASSETS")',
data: data,
success: function (resp) {
if (resp.ModelExists)
{
alert("Model [" + resp.Text + "] already exists. Please select from the DropDown.");
} else {
$('#selectModel').append($('<option></option>').val(resp.MODEL_ID).text(resp.Text));
form[0].reset();
$('#createModelFormContainer').hide();
var count = $('#selectModel option').size();
$('#selectModel').prop('selectedIndex', count - 1);
$('#selectModel').val(resp.MODEL_ID);
//document.getElementById('selectModel').value = resp.MODEL_ID; - Shows dropdown as blank [ ] once executed.
}
},
error: function () {
alert("ERROR - Something went wrong adding new Model [" + resp.Text + "]!");
$('#createModelFormContainer').hide();
}
});
//reloadForNewEntity();
});
我的控制器中调用的createNewModel()
方法:
public JsonResult createNewModel(string description)
{
DBT_MODELS model = new DBT_MODELS()
{
// ID auto-set during save.
MODEL_DESCRIPTION = description.Trim(),
CREATED_DATE = DateTime.Now,
CREATED_BY = System.Environment.UserName
};
var duplicateModel = db.DBT_MODELS.FirstOrDefault(x => x.MODEL_DESCRIPTION.ToUpper() == model.MODEL_DESCRIPTION.ToUpper());
try
{
if (duplicateModel == null)
{
if (ModelState.IsValid)
{
db.DBT_MODELS.Add(model);
db.SaveChanges();
// Ensure the [model.ID] is properly set after having been saved to and auto-generated in the database.
model.MODEL_ID = db.DBT_MODELS.FirstOrDefault(x => x.MODEL_DESCRIPTION.ToUpper() == model.MODEL_DESCRIPTION.ToUpper()).MODEL_ID;
}
}
else
{
model = duplicateModel;
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = model.MODEL_ID, Text = model.MODEL_DESCRIPTION, ModelExists = (duplicateModel != null) }, JsonRequestBehavior.AllowGet);
}
从视觉上讲,到目前为止,一切都按预期进行。问题是当我去保存主要实体我正在创建/编辑。
在外表中已经存在的任何值,因此在View加载时的DropDownList中,保存得很好;但是如果我为这些主要实体属性添加新的外部表值(虽然可视地添加了各个DropDownLists的当前选定值),然后执行[POST]
方法,并将每个外部id值设置为0
(例如,MainClass.Model_ID =&#34; 0&#34; vs期望MainClass.Model_ID =&#34; 625&#34;,MainClass.Type_ID =&#34; 0&#34; vs期望MainClass.Type_ID =&#34 ; 17&#34;,MainClass.Location_ID =&#34; 0&#34; vs期望MainClass.Location_ID =&#34; 82&#34;等。)
基本上,如果Html.DropDownListFor()
中选择的值是我新添加的值之一,则POST
控制器方法始终呈现所选MainClass.*_ID
值对应的Html.DropDownListFor()
值as&#34; 0&#34;。
有谁能指出我如何使这个工作?我试过了:
//document.getElementById('selectModel').value = resp.MODEL_ID; - Shows dropdown as blank [ ] once executed.
vs $('#selectModel').val(resp.MODEL_ID);
,它可视地呈现DropDownList中的预期新值。 / LI>
@Viewbag.PostModelID = resp.ModelID
渲染为&#34; = resp.ModelID& #34;并抛出了许多预期的错误。)修改:
[N / A编辑]
EDIT2 :很高兴。谢谢大家的建议!
答案 0 :(得分:1)
您从操作方法返回的json数据采用此格式。
{
"ID": 24,
"Text": "IOS",
"ModelExists": false
}
但是在您的代码中,您正在尝试访问resp对象中不存在的MODEL_ID
属性。
$('#selectModel').append($('<option></option>').val(resp.MODEL_ID).text(resp.Text));
将代码更改为使用ID
属性值
$('#selectModel').append($('<option></option>').val(resp.ID).text(resp.Text));
$('#selectModel').val(resp.ID);
答案 1 :(得分:0)
在您创建新模型的控制器中..您返回的json对象是ID, Text, ModelExists
,但在您的javascript中,您将新<option>
的val属性设置为{ {1}} ..这两个需要匹配..
因此,将您的javascript更改为
MODEL_ID
或将控制器操作中的返回值更改为
.val(resp.ID)
您还在这里引用return Json(new { MODEL_ID = model.MODEL_ID, Text = model.MODEL_DESCRIPTION
MODEL_ID
因此,如果您不更改控制器操作,请同时更新