通过用户输入添加项目到列表

时间:2013-11-08 03:02:12

标签: c# asp.net asp.net-mvc-4

我在ASP.NET MVC上经历了一些教程(herehere),并决定自己尝试一些事情。现在,我有三个表,ResumeDescriptionsSubDescriptions。这是三个代码:

public class Resume
{
    public Resume()
    {
        Descriptions = new List<Description>();
    }

    [Key]
    public int ResumeId { get; set; }

    [Required]
    public string Employer { get; set; }

    [DataType(DataType.Date)]
    public DateTime StartDate { get; set; }

    [DataType(DataType.Date)]
    public DateTime EndDate { get; set; }

    [Required]
    public string Location { get; set; }

    [Required]
    public virtual ICollection<Description> Descriptions { get; set; }
}

public class Description
{
    public Description()
    {
        SubDescriptions = new List<SubDescription>();
    }

    [Key]
    public int DescriptionId { get; set; }

    [ForeignKey("Resume")]
    public int ResumeId { get; set; }

    [Required]
    public string Desc { get; set; }

    public virtual Resume Resume { get; set; }

    public virtual ICollection<SubDescription> SubDescriptions { get; set; }
}

public class SubDescription
{
    [Key]
    public int SubDescriptionId { get; set; }

    [ForeignKey("Description")]
    public int DescriptionId { get; set; }

    [Required]
    public string Sub { get; set; }

    public virtual Description Description { get; set; }
}

现在,我遇到的问题是Create视图。我想创建一个新的Resume条目。但是,我遇到了添加Descriptions的问题。这是我的Create视图:

@model Portfolio.Models.Resume

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Resume</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Employer)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Employer)
            @Html.ValidationMessageFor(model => model.Employer)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.StartDate)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.StartDate)
            @Html.ValidationMessageFor(model => model.StartDate)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.EndDate)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.EndDate)
            @Html.ValidationMessageFor(model => model.EndDate)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Location)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Location)
            @Html.ValidationMessageFor(model => model.Location)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Descriptions)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Descriptions)
            @Html.ValidationMessageFor(model => model.Descriptions)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

问题是,由于Descriptions是一个列表,实际上没有任何内容可以添加。我甚至不确定如何解决这个问题。我希望能够添加Description,然后可以选择在事后添加SubDescription。这甚至是可能的,还是我尝试了一些完全错综复杂的事情?

修改

添加此编辑以获得更多说明。我试图确定如何让用户填充Descriptions视图中的Create列表。我在考虑使用listbox。然后,他们可以选择Description,然后添加SubDescription。但我并不是100%肯定如何做到这一点。我尝试将@Html.EditorFor(model => model.Descriptions)更改为@Html.ListBoxFor(model => model.Descriptions),但我收到错误no overload for ListBoxFor takes 1 argument.因为我还是新手并且学习了这个,我不知道怎么做去完成我想做的事。

2 个答案:

答案 0 :(得分:1)

你走在正确的轨道上! ListBoxFor方法有两个参数。第一个是你现在拥有的。第二个参数是IEnumerable<SelectListItem>对象。

我之前亲自做过这种事情,使用ListBoxFor方法真的很有帮助。您可以创建List<SelectListItem>,每个项目都可以保存存储在描述对象中的信息。

如果您将List<SelectListItem>对象从Controller传递给View,您可以向用户显示所有Descriptions对象,他们可以选择并添加他们选择的对象。

您还可以创建单独的视图,并根据您尝试的操作在某些情况下将用户重定向到这些视图。

祝你好运! =)

答案 1 :(得分:1)

@ RobG31415给了你一个很好的答案,但我从经验中知道第一次使用ListBoxFor和DropDownListFor是一个真正的痛苦,所以我会给你一点点。

创建简历

您可以将ViewModel或模型传递给仅包含说明的视图。由于SubDescriptions取决于您选择的描述,因此您需要具有级联下拉列表。

Create a dropdown列出了您在此行中的描述:

@Html.DropDownListFor(x => x.DescriptionId, new SelectList(Model.Descriptions.Select(m => new SelectListItem()
{
    Text = m.Desc,
    Value = m.DescriptionId.ToString()
})), "Choose", new { id = "Descriptions" })

之后,为子描述添加一个空的下拉列表

@Html.DropDownList("SubDescriptionId", new SelectList(new List<SelectListItem>()), new { id = "SubDescriptions" })

DropDownListFor中的第一个表达式指向一个modelproperty,用于存储下拉列表中的选定值,这将是DescriptionId。 现在我们必须使用jquery和ajax创建级联下拉效果。我们在“描述”下拉列表中添加一个onchange事件,以获取数据库中的所有SubDescriptions。

$('#Descriptions').change(function() {
    var descId = $('#Descriptions:selected').val();
    $.ajax({
        type: 'GET',
        url: '/Resume/GetSubDescriptions'
        data: { id = descId },
        success: function(data) {
            //TODO: Add SubDescriptions to the dropdown
        }
    });
});

创建描述/子描述

这只是创建简历的部分。如果你需要让用户有可能创建他们自己的描述,我想你应该在下拉列表中有一个按钮或选项说“创建描述”,一个用于SubDescription。 这可以在顶部打开一个新窗口或向下滑动隐藏的div,或者你想出的任何东西。这部分你可以作为partial view或原始视图的一部分 从Description开始,这只需要一个字符串,所以普通的Html.TextBox和一个保存它的按钮应该是你现在需要的一切。用户填写文本框并按下save后,使用ajax将字符串发送到控制器,然后让它返回创建的描述

$('#createDescription').click(function() {
    var desc = $('#newDescription').val();
    $.ajax({
        type: 'POST',
        url: '/Resume/CreateDescription'
        data: { desc = desc },
        success: function(data) {
            //TODO: Add the returned description to the drop-downs
        }
    });
});

public JsonResult CreateDescription(string desc)
{
    Description description = _resumeService.CreateDescription(desc);
    return Json(description);
}

要创建您的SubDescription,您需要先选择一个描述,然后为它选择一个名称,这样看起来会相同,但下拉列表中包含所有描述的下拉列表,如下所示,然后是名称的文本框,以及将这两个值发布到控制器。

需要考虑的一些事项:

在与创建简历的表单相同的表单上创建Description和SubDescription的问题是,您可能不希望每次创建新内容时都重新加载整个页面。这很容易导致很多javascript / jQuery使用正确的数据更新你的dropdown等。发布整个表单并重新加载页面将使您更容易在下拉列表中获得正确的数据,但也会给您的网站带来不太专业的感觉。

旁注:

我首先要做的是设置ViewModel而不是使用真实模型。由于您可能需要在视图中进行验证和不同的数据集,因此在不使模型混乱的情况下实现最佳方法的方法是ViewModels。 为了便于使用viewmodel,我喜欢使用Automapper将数据从模型映射到viewmodel并返回。如果需要,您还可以将视图模型中的数据映射到其他视图模型。