简体   繁体   English

如何将动态加载的局部视图与父模型绑定

[英]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.

相关问题 如何访问父视图中部分视图的Model? - How to access the Model of a partial view in the parent view? 如何在部分视图中绑定嵌套模型 - How to bind nested model in partial view 如何使用模型在mvc 4中部分视图中绑定下拉列表? - How to bind dropdownlist in partial view in mvc 4 using model? 将另一个模型绑定到局部视图,如嵌套局部视图绑定 - bind another model to partial view like nested partial view binding 使用ajax添加部分视图时,如何将部分视图列表绑定到模型 - How to bind a list of partial views to a model when the partial view is added with ajax 如何将 ItemsControl 成员的 ICommand 的依赖属性绑定到父视图 model? - How to bind dependency property of ICommand of ItemsControl member to parent view model? 将父模型的一个元素传递到局部视图 - To pass one element of parent model to partial view 如何将视图模型绑定到视图 - How to bind the view model to the view 当父视图具有相同模型时,如何将局部视图中的 HTML 表单数据序列化? - How do I get HTML form data in Partial View to be serialized when parent view has same model? 如何检查是否加载了部分视图,然后加载javascript - how to check if partial view is loaded and then load javascript
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM