[英]How to bind dynamically loaded partial view with parent Model
I'm currently using a Partial view to add dynamic items to a table. 我目前正在使用部分视图向表中添加动态项。
The table is contained in a Wizard , the wizard uses knockoutjs to bind data. 该表包含在向导中 ,该向导使用knockoutjs绑定数据。
Currently, the partial view added successfully. 目前,部分视图已成功添加。 However, the values entered in the Partial view are not binding back to the main Model. 但是,在“部分”视图中输入的值不会绑定回主模型。
I have search SO and the web for solutions, but could not found any. 我搜索SO和网络寻求解决方案,但找不到任何解决方案。
My Partial View: 我的部分观点:
@model Question.Models.LiabilityModel
<tr>
@using (@Html.BeginCollectionItem("Liabilities")) {
<td>
@Html.DropDownListFor(model => model.Type, Model.Types, new { @class = "form-control selectpicker", id = "" })
</td>
<td>
@Html.TextBoxFor(model => model.Name, new { @class = "form-control", id = "" })
</td>
<td>
@Html.TextBoxFor(model => model.Balance, new { @class = "form-control auto", id = "" })
</td>
<td>
@Html.TextBoxFor(model => model.Payment, new { @class = "form-control auto", id = "" })
</td>
<td>
@Html.TextBoxFor(model => model.Interest, new { @class = "form-control", id = "", @type = "number" })
</td>
<td>
@Html.TextBoxFor(model => model.Teams, new { @class = "form-control", id = "", @type = "number" })
</td>
<td>
@Html.TextBoxFor(model => model.Tenure, new { @class = "form-control", id = "", @type = "number" })
</td>
<td>
<button class="btn btn-primary remove-button" type="button" data-id="@Model.ID">
<span class="glyphicon glyphicon-trash"></span>
</button>
</td>
}
Table: 表:
<table id="LibList" class="table table-responsive table-condensed table-striped">
<thead>
<tr>
<th style="width: 150px;">
@Html.DisplayNameFor(model => model.Step3.Liabilities[0].Types)
</th>
<th>
@Html.DisplayNameFor(model => model.Step3.Liabilities[0].Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Step3.Liabilities[0].Balance)
</th>
<th>
@Html.DisplayNameFor(model => model.Step3.Liabilities[0].Payment)
</th>
<th>
@Html.DisplayNameFor(model => model.Step3.Liabilities[0].Interest)
</th>
<th>
@Html.DisplayNameFor(model => model.Step3.Liabilities[0].Teams)
</th>
<th>
@Html.DisplayNameFor(model => model.Step3.Liabilities[0].Tenure)
</th>
<th>
Delete
</th>
</tr>
</thead>
<tbody>
@for (var i = 0; i < Model.Step3.Liabilities.Count; i++) {
Html.RenderPartial("_LibListItem", Model.Step3.Liabilities[i]);
}
</tbody>
</table>
Existing items are added when the page loads for the first time. 第一次加载页面时会添加现有项目。 Then the user can later add more items which are dynamically added to the table. 然后,用户可以稍后添加更多动态添加到表中的项目。
Has items are added to the table, I want the new items add to: 是否已将项目添加到表格中,我希望将新项目添加到:
Model.Step3.Liabilities
On post back. 在回帖后。
Add Function: 添加功能:
$('.add-button').click(function () {
var action = "/QuestionWizard/AddRow";
$.ajax({
url: action,
cache: false,
success: function (result) {
$("#LibList").find("tbody").append($(result));
$("#LibList").find("tbody").find('.selectpicker').last().selectpicker();
}
});
});
Add Action: 添加动作:
public ActionResult AddRow() {
LiabilityModel lib = new LiabilityModel();
try {
if (LiabilitySessionState.Count == 0) {
LiabilitySessionState = ((QuestionWizardViewModel)this.ViewModelSessionState).Step3.Liabilities;
}
lib.ID = LiabilitySessionState.LastOrDefault().ID + 1;
LiabilitySessionState.Add(lib);
} catch (Exception) {
return Json(null);
}
return PartialView("_LibListItem", lib);
}
My Model: 我的型号:
public class WizardViewModelThirdStep : ModelBase {
[Display(Name = "Liabilities")]
public List<LiabilityModel> Liabilities { get; set; }
public void getInitialItems() {
Liabilities = new List<LiabilityModel>();
//initial item
LiabilityModel model = new LiabilityModel();
model.ID = 1;
Liabilities.Add(model);
}
}
public class LiabilityModel : ModelBase {
public int ID { get; set; }
[Display(Name = "Type", Prompt = "Type")]
public List<SelectListItem> Types { get; set; }
public LIA Type { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
[Display(Name = "Name of Institution.", Prompt = "Name of Institution.")]
public string Name { get; set; }
[Display(Name = "Balance ($).", Prompt = "Balance ($).")]
[DataType(DataType.Currency)]
public decimal Balance { get; set; }
[Display(Name = "Payment ($).", Prompt = "Payment ($).")]
[DataType(DataType.Currency)]
public decimal Payment { get; set; }
[Display(Name = "Interest (%).", Prompt = "Interest (%).")]
public decimal Interest { get; set; }
[Display(Name = "Teams", Prompt = "Teams")]
public decimal Teams { get; set; }
[Display(Name = "Tenure", Prompt = "Tenure")]
public decimal Tenure { get; set; }
public LiabilityModel() {
ID = 0;
Types = new List<SelectListItem>();
}
} }
These are the post back methods: 这些是回发方法:
protected override void ProcessToNext(WizardViewModel model) {
((QuestionWizardViewModel)model).PageTitle = GetDisplayName(typeof(QuestionWizardViewModel), "Step" + model.StepIndex);
}
protected override void ProcessToPrevious(WizardViewModel model) {
((QuestionWizardViewModel)model).PageTitle = GetDisplayName(typeof(QuestionWizardViewModel), "Step" + model.StepIndex);
}
Thanks for the help! 谢谢您的帮助!
You should not render partial for each item. 您不应为每个项目渲染部分内容。 You should render it for whole list and MVC will take care of repeating it and indexing input fields correctly. 您应该将其呈现为整个列表,MVC将负责重复它并正确地索引输入字段。
So you should move your PartialView
contents to EditorTemplate
and then in your form use: 因此,您应该将PartialView
内容移动到EditorTemplate
,然后在表单中使用:
<tbody>
@Html.EditorFor(Model.Step3.Liabilities)
</tbody>
Remember that you need to create a template for one item and use this template on whole list (like above). 请记住,您需要为一个项目创建一个模板,并在整个列表中使用此模板(如上所述)。
My final solution: 我的最终解决方案
<tbody data-bind="template: { name: 'LibRowTemplate', foreach: Model.Step3.Liabilities }"></tbody>
Template: 模板:
<script type="text/html" id="LibRowTemplate">
<tr>
<td>
<select class="form-control selectpicker" data-bind="value: SelectedType, uniqueName: true">
<option value="NONE">Select a Type</option>
<option value="Loan">Loan</option>
<option value="Investment">Investment</option>
<option value="Others">Others</option>
</select>
</td>
<td>
<input class="form-control" data-bind="value: Name, uniqueName: true" />
</td>
<td>
<input class="form-control" data-bind="value: Balance, uniqueName: true" />
</td>
<td>
<input class="form-control" data-bind="value: Payment, uniqueName: true" />
</td>
<td>
<input class="form-control" data-bind="value: Interest, uniqueName: true" />
</td>
<td>
<input class="form-control" data-bind="value: Teams, uniqueName: true" />
</td>
<td>
<input class="form-control" data-bind="value: Tenure, uniqueName: true" />
</td>
<td>
<button class="btn btn-primary remove" type="button">
<span class=" glyphicon glyphicon-trash"></span>
</button>
</td>
</tr>
knockout ModelView: 淘汰模型:
self.AddLib = function () {
self.Model.CurrentStep().Liabilities.push({ SelectedType: "", Name: "", Balance: "0", Payment: "0", Interest: "0", Teams: "0", Tenure: "0" });
}
self.DelLib = function (element) {
self.Model.CurrentStep().Liabilities.remove(element);
}
$("#tablelib").delegate(".remove", "click", function () {
vm.DelLib(ko.dataFor(this));
});
Add Button: 添加按钮:
<button type="button" class="btn btn-primary" data-bind="event:{ click: AddLib }">
<span class="glyphicon glyphicon-plus"></span> Add New
</button>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.