【问题标题】:How to use @model IEnumerable<> and @model <> in the same page (List / Create) MVC3如何在同一页面(列表/创建)MVC3 中使用@model IEnumerable<> 和@model <>
【发布时间】:2012-08-13 17:49:53
【问题描述】:

假设我有一个“位置”类,我正在使用 MVC3 创建一个脚手架列表 (index.cshtml)。 index html 页面使用@model IEnumerable。如果我想在列表中添加一个新位置,我按创建,最后我会使用@model Project.Models.Location 得到一个新的 html 页面。

我不想进入新页面,而是希望使用 boostrap(twitter) 中的模式将创建页面作为弹出窗口。我试过使用 partialview 没有任何运气。无论我做什么,我都会收到字典错误消息。

传入字典的模型项的类型为“System.Data.Entity.Infrastructure.DbQuery`1[Project.Models.Location]”,但此字典需要“Project.Models.Location”类型的模型项.

当我不获取局部视图时,模态(引导)本身正在工作。部分视图本身与生成的 create(CRUD) 完全相同。

编辑:我重写了整件事。

索引:

@model IEnumerable<LoLStats.Models.Location>

@{
    ViewBag.Title = "Index";
}
@foreach (var item in Model) {
    <ul>
        <li>@Html.DisplayFor(modelItem => item.LocationName)</li>
    </ul>
}

<a class="btn" data-toggle="modal" href="#myModal" >Create</a>

<div class="modal hide" id="myModal">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal">×</button>
    <h3>Modal header</h3>
  </div>
  <div class="modal-body">
    <p>@Html.Partial("_createLocation")</p>
  </div>
  <div class="modal-footer">
    <a href="#" class="btn" data-dismiss="modal">Close</a>
    <a href="#" class="btn btn-primary">Save changes</a>
  </div>
</div>

_createLocation:

@model LoLStats.Models.Location

@{ ViewBag.Title = "创建"; }

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

    <div class="editor-label">
        @Html.LabelFor(model => model.LocationName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.LocationName)
        @Html.ValidationMessageFor(model => model.LocationName)
    </div>
    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset> }

【问题讨论】:

  • 您将项目拼写错误“Prosject.Models.Cars”
  • 那不是问题。我手头没有确切的错误消息,所以我写了它。不过还是谢谢 :)
  • 请同时发布您目前拥有的代码

标签: asp.net-mvc-3


【解决方案1】:

您可以创建一个具有两个属性的视图模型:

  • 父视图的 IEnumerable
  • 模态的奇异对象

然后在视图模型中强烈键入两个视图,您应该已经准备好了。

编辑

视图模型:

public class MyViewModel()
{
  public IEnumerable<LoLStats.Models.Location> Locations {get; set;}
  public LoLStats.Models.Location Location {get; set;}
}

索引:

@model myNamespace.MyViewModel
...
@foreach (var item in Model.Locations) {
    <ul>
        <li>@Html.DisplayFor(modelItem => item.Locations.LocationName)</li>
    </ul>
...

_createLocation:

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

希望这些细节足以让您继续前进

【讨论】:

  • 从最佳实践的角度来看,尽量避免使用@model IEnumerable&lt;whatever&gt;,即泛型类型。最好的方法是创建专用于该特定视图的视图模型(通常每个视图 1 个视图模型)并在其中包含所有视图需要显示并回发到您的控制器。
  • @Forty-2 仍然遇到同样的错误,但明天再看一遍
【解决方案2】:

在索引视图中试试这个:

   ... <p>@Html.Partial("_createLocation", Model.FirstOrDefault())</p>

另一方面,也许这会更有意义:

   ... <p>@Html.Partial("_createLocation", new LoLStats.Models.Location())</p>

希望它对你有用。

【讨论】:

    【解决方案3】:

    您的弹出窗口需要定义为Project.Models.Car(单项)的模型。成功保存单个项目后,您需要更新原始列表视图。您可以使用 jQuery 通过将新项目插入 DOM 或通过导航到为您提供开始列表的操作来刷新页面来执行此操作。

    【讨论】:

    • 在我更新我的帖子后这仍然算数吗?顺便说一句,对不起
    • 我的方法和包含复合 ViewModel 的答案都以不同的方式实现了相同的结果。在 MS 代码中总是有 476 种方法可以给猫剥皮 :-)
    • 就个人而言,我倾向于分解我的 UI 以减少耦合。我喜欢有 2 个特定视图,一个用于列表,另一个用于编辑。保存新项目后,我重定向回列表。但这只是我。
    • 这是一种思考方式,可能会或可能不会影响您的决定。假设您有一个汽车列表,您是否要求显示这些汽车的所有字段?如果是这样,如果添加要编辑的新字段,这会影响您必须在列表中显示的内容吗?如果您只在 List 中显示几个主要字段,并且 Edit 视图包含所有字段,那么您在实现 Composite ViewModel 时应该没有任何问题。所以做最适合您要求的事情:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-30
    • 1970-01-01
    • 2022-06-25
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多