4

我正在浏览一些关于 ASP.NET MVC 的教程(此处此处),并决定自己尝试一些事情。现在,我有三张桌子Resume,,,,。以下是三者的代码:DescriptionsSubDescriptions

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是一个列表,实际上没有任何内容可以添加。我什至不确定该怎么做。我希望能够添加 a Description,然后可以选择在SubDescription事后添加 a 。这甚至可能吗,还是我正在尝试一些完全令人费解的事情?

编辑

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

4

2 回答 2

1

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

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

如果您将List<SelectListItem>对象从控制器传递给视图,您可以向用户显示所有描述对象,他们可以选择和添加他们选择的任何对象。

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

祝你好运!=)

于 2013-11-12T01:59:33.633 回答
1

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

创建简历

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

沿着这条线为您的描述创建一个下拉列表:

@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 中的第一个表达式指向一个模型属性,用于存储从下拉列表中选择的值,即 DescriptionId。现在我们必须使用 jquery 和 ajax 创建级联下拉效果。我们在 Descriptions 下拉列表中添加一个 onchange 事件,以便从 db 中获取所有 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,或者您想出什么。这部分您可以作为局部视图或仅作为原始视图的一部分。
从描述开始,这只需要一个字符串,所以一个普通的 Html.TextBox 和一个保存它的按钮应该是你现在需要的一切。用户填写文本框并推送保存后,使用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,您需要首先选择一个描述,然后为其选择一个名称,所以这看起来是一样的,但是有一个包含我之前显示的所有描述的下拉列表,然后是一个名称的文本框,然后发布这两个值给控制器。

需要考虑的一些事项:

在与创建简历相同的表单上创建描述和子描述的问题在于,您可能不希望每次创建新内容时都重新加载整个页面。这很容易导致大量的 javascript/jQuery 使用正确的数据来更新您的下拉列表等。发布整个表单并重新加载页面将使您更轻松地在下拉列表中拥有正确的数据,但也会给您的网站带来不那么专业的感觉。

边注:

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

于 2013-11-14T02:28:28.373 回答