具有BeginCollectionItem的MVC 5动态行 [英] MVC 5 Dynamic Rows with BeginCollectionItem

查看:41
本文介绍了具有BeginCollectionItem的MVC 5动态行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

单击按钮时向表添加/删除行的最佳方法是什么?我需要从ChildClass属性创建的行(子类是主类/模型内的列表).

What is the best way to add/delete rows to a table when a button is clicked? I need rows created from ChildClass properties (child class is a list within the main class/model).

当前有一个视图(模型为MyMain),该视图使用RenderPartial引用了部分视图.

Currently have a View (model is MyMain) which references a Partial View using RenderPartial.

局部视图显示模型的属性,该类称为MyChild,是MyMain中的对象列表.

The partial view displays the properties of the model, a class called MyChild which is an object list within MyMain.

我想要添加和删除按钮来动态添加部分视图中保存的行.

I want to have add and delete buttons to dynamically add the rows which are held within the partial view.

因此重复添加MyChild以获得列表上的更多行. 这可能吗?还是我不应该为此使用局部视图?

So adding MyChild repeatedly for more rows on the list. Is this possible? Or should I not be using partial views for this?

更新代码

下面是我正在使用的当前类和视图,我一直在尝试实现BeginCollectionItem帮助器,但是尽管if语句说要创建,但我在尝试加载部分视图的地方却得到了null ref.子类的新实例(如果不存在)-为什么将其忽略?

Below are the current classes and views I'm working with, I've been trying to implement the BeginCollectionItem helper but I'm getting null ref where I'm trying to load the partial view despite the if statement saying to create a new instance of the child class if doesn't exist - why is this being ignored?

主视图

    @using (Html.BeginForm())
{
    <table>
        <tr>
            <th>MyMain First</th>
            <th>MyChild First</th>
        </tr>
        <tr>
            <td>
                @Html.EditorFor(m => m.First)
            </td>
            <td>
                @if (Model.child != null)
                {
                    for (int i = 0; i < Model.child.Count; i++)
                    {
                        Html.RenderPartial("MyChildView");
                    }
                }        
                else
                {
                    Html.RenderPartial("MyChildView", new MvcTest.Models.MyChild());
                }       
            </td>
        </tr>
        @Html.ActionLink("Add another", "Add", null, new { id = "addItem" })
    </table>
}

局部视图

@model MvcTest.Models.MyChild

@using (Html.BeginCollectionItem("myChildren"))
{
    Html.EditorFor(m => m.Second);
}

模型

public class MyMain
{
    [Key]
    public int Id { get; set; }
    public string First { get; set; }
    public List<MyChild> child { get; set; }
}

public class MyChild
{
    [Key]
    public int Id { get; set; }
    public string Second { get; set; }
}

控制器

public class MyMainsController : Controller
{
    // GET: MyMains
    public ActionResult MyMainView()
    {
        return View();
    }

    [HttpPost]
    public ActionResult MyMainView(IEnumerable<MyChild> myChildren)
    {
        return View("MyMainView", myChildren);
    }

    public ViewResult Add()
    {
        return View("MyChildView", new MyChild());
    }
}

推荐答案

更新后的答案-原始代码为动态",但是它允许所有操作我需要在问题参数中进行操作.

Updated Answer - The original code is NOT true to 'dynamic', however it allows for everything I needed to do within the question parameters.

最初,在问题评论中我无法获得Stephen的BCI建议,因为从那时起我就拥有了,这是很棒的.如果您复制并粘贴,下面更新部分中的代码将起作用,但是您需要从GIT手动下载BCI或在Visual Studio中将PM> Install-Package BeginCollectionItem与Package Manager控制台一起使用.

Initially, I couldn't get Stephen's BCI suggestion in the question comments working, since then I have and it's brilliant. The code below in the updated section will work if you copy + paste, but you will need to either manually download BCI from GIT or use PM> Install-Package BeginCollectionItem with Package Manager Console in Visual Studio.

由于复杂性,我之前在使用BCI的各个方面存在一些问题,并且之前没有做过MVC-

I had some issue with various points using BCI due to the complexity and not having done MVC before - here is more information on dealing with accessing class.property(type class).property(type class).property.

原始答案-与下面的问题相比,我在下面给出了一个更清晰的示例,但很快就会感到困惑.

Original answer - I've gone with a more clear example below than in my question which quickly got too confusing.

使用两个局部视图,一个用于雇员列表,另一个用于创建新雇员,所有视图都包含在companyemployee的视图模型中,该模型包含公司对象和雇员对象列表.这样,可以从列表中添加,编辑或删除多个员工.

Using two partial views, one for the list of employees and another for the creation of a new employee all contained within the viewmodel of companyemployee which contains an object of company and a list of employee objects. This way multiple employees can be added, edited or deleted from the list.

希望这个答案可以帮助寻找相似内容的任何人,这应该提供足够的代码以使其正常工作,至少可以将您推向正确的方向.

Hopefully this answer will help anyone looking for something similar, this should provide enough code to get it working and at the very least push you in the right direction.

我省略了上下文和初始化器类,因为它们只对代码优先,如果需要,我可以添加它们.

I've left out my context and initialiser classes as they're only true to code first, if needed I can add them.

感谢所有提供帮助的人.

Thanks to all who helped.

模型-CompanyEmployee是视图模型

Models - CompanyEmployee being the view model

public class Company
{
    [Key]
    public int id { get; set; }
    [Required]
    public string name { get; set; }
}

public class Employee
{
    [Key]
    public int id { get; set; }
    [Required]
    public string name { get; set; }
    [Required]
    public string jobtitle { get; set; }
    [Required]
    public string number { get; set; }
    [Required]
    public string address { get; set; }
}

public class CompanyEmployee
{
    public Company company { get; set; }
    public List<Employee> employees { get; set; }
}

索引

@model MMV.Models.CompanyEmployee
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>
<fieldset>
    <legend>Company</legend>
    <table class="table">
        <tr>
            <th>@Html.LabelFor(m => m.company.name)</th>
        </tr>
        <tr>
            <td>@Html.EditorFor(m => m.company.name)</td>
        </tr>
    </table>
</fieldset>
<fieldset>
    <legend>Employees</legend>

        @{Html.RenderPartial("_employeeList", Model.employees);}

</fieldset>
<fieldset>
    @{Html.RenderPartial("_employee", new MMV.Models.Employee());}
</fieldset>
<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" value="Submit" class="btn btn-default" />
    </div>
</div>

部分员工名单

@model IEnumerable<MMV.Models.Employee>
@using (Html.BeginForm("Employees"))
{
    <table class="table">
        <tr>
            <th>
                Name
            </th>
            <th>
                Job Title
            </th>
            <th>
                Number
            </th>
            <th>
                Address
            </th>
            <th></th>
        </tr>
        @foreach (var emp in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => emp.name)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => emp.jobtitle)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => emp.number)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => emp.address)
                </td>
                <td>
                    <input type="submit" formaction="/Employees/Edit/@emp.id" value="Edit"/>
                    <input type="submit"formaction="/Employees/Delete/@emp.id" value="Remove"/>
                </td>
            </tr>
        }
    </table>
}

部分视图创建员工

@model MMV.Models.Employee

@using (Html.BeginForm("Create","Employees"))
{
    <table class="table">

        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <tr>
            <td>
                @Html.EditorFor(model => model.name)
                @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
            </td>
            <td>
                @Html.EditorFor(model => model.jobtitle)
                @Html.ValidationMessageFor(model => model.jobtitle)
            </td>
            <td>
                @Html.EditorFor(model => model.number)
                @Html.ValidationMessageFor(model => model.number, "", new { @class = "text-danger" })
            </td>
            <td>
                @Html.EditorFor(model => model.address)
                @Html.ValidationMessageFor(model => model.address, "", new { @class = "text-danger" })
            </td>
        </tr>
    </table>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
}

控制器-我使用了多个,但您可以将它们全部放在一个

Controller - I used multiple but you can put them all in one

public class CompanyEmployeeController : Controller
{
    private MyContext db = new MyContext();

    // GET: CompanyEmployee
    public ActionResult Index()
    {
        var newCompanyEmployee = new CompanyEmployee();
        newCompanyEmployee.employees = db.EmployeeContext.ToList();
        return View(newCompanyEmployee);
    }

    [HttpPost, ActionName("Delete")]
    public ActionResult DeleteConfirmed(int id)
    {
        Employee employee = db.EmployeeContext.Find(id);
        db.EmployeeContext.Remove(employee);
        db.SaveChanges();
        return RedirectToAction("Index", "CompanyEmployee");
    }

    [HttpPost]
    public ActionResult Create([Bind(Include = "id,name,jobtitle,number,address")] Employee employee)
    {
        if (ModelState.IsValid)
        {
            db.EmployeeContext.Add(employee);
            db.SaveChanges();
            return RedirectToAction("Index", "CompanyEmployee");
        }

        return View(employee);
    }
}

更新的代码-使用BeginCollectionItem-动态添加/删除

部分学生

@model UsefulCode.Models.Person
<div class="editorRow">
    @using (Html.BeginCollectionItem("students"))
    {
        <div class="ui-grid-c ui-responsive">
            <div class="ui-block-a">
                <span>
                    @Html.TextBoxFor(m => m.firstName)
                </span>
            </div>
            <div class="ui-block-b">
                <span>
                    @Html.TextBoxFor(m => m.lastName)
                </span>
            </div>
            <div class="ui-block-c">
                <span>
                    <span class="dltBtn">
                        <a href="#" class="deleteRow">X</a>
                    </span>
                </span>
            </div>
        </div>
    }
</div>

教师部分

@model UsefulCode.Models.Person
<div class="editorRow">
    @using (Html.BeginCollectionItem("teachers"))
    {
        <div class="ui-grid-c ui-responsive">
            <div class="ui-block-a">
                <span>
                    @Html.TextBoxFor(m => m.firstName)
                </span>
            </div>
            <div class="ui-block-b">
                <span>
                    @Html.TextBoxFor(m => m.lastName)
                </span>
            </div>
            <div class="ui-block-c">
                <span>
                    <span class="dltBtn">
                        <a href="#" class="deleteRow">X</a>
                    </span>
                </span>
            </div>
        </div>
    }
</div>

注册控制器

public ActionResult Index()
{
    var register = new Register
    {
        students = new List<Person>
        {
            new Person { firstName = "", lastName = "" }
        },
        teachers = new List<Person> 
        {
            new Person { lastName = "", firstName = "" }
        }
    };

    return View(register);
}

注册和人员模型

public class Register
{
    public int id { get; set; }
    public List<Person> teachers { get; set; }
    public List<Person> students { get; set; }
}

public class Person
{
    public int id { get; set; }
    public string firstName { get; set; }
    public string lastName { get; set; }
}

索引

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@model UsefulCode.Models.Register
<div id="studentList">
@using (Html.BeginForm())
{
    <div id="editorRowsStudents">
        @foreach (var item in Model.students)
        {
            @Html.Partial("StudentView", item)
        }
    </div>
    @Html.ActionLink("Add", "StudentManager", null, new { id = "addItemStudents", @class = "button" });
}
</div>

<div id="teacherList">
@using (Html.BeginForm())
{
    <div id="editorRowsTeachers">
        @foreach (var item in Model.teachers)
        {
            @Html.Partial("TeacherView", item)
        }
    </div>
    @Html.ActionLink("Add", "TeacherManager", null, new { id = "addItemTeachers", @class = "button" });
}
</div>


@section scripts {
    <script type="text/javascript">
    $(function () {
        $('#addItemStudents').on('click', function () {
            $.ajax({
                url: '@Url.Action("StudentManager")',
                    cache: false,
                    success: function (html) { $("#editorRowsStudents").append(html); }
                });
                return false;
            });
            $('#editorRowsStudents').on('click', '.deleteRow', function () {
                $(this).closest('.editorRow').remove();
            });
            $('#addItemTeachers').on('click', function () {
                $.ajax({
                    url: '@Url.Action("TeacherManager")',
                    cache: false,
                    success: function (html) { $("#editorRowsTeachers").append(html); }
                });
                return false;
            });
            $('#editorRowsTeachers').on('click', '.deleteRow', function () {
                $(this).closest('.editorRow').remove();
            });
        });
    </script>
}

StudentManager操作:

StudentManager Action:

public PartialViewResult StudentManager()
{
    return PartialView(new Person());
}

这篇关于具有BeginCollectionItem的MVC 5动态行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆