【问题标题】:Re-using a partial view (ascx) across different Controllers and Views跨不同控制器和视图重用局部视图(ascx)
【发布时间】:2010-11-01 10:49:51
【问题描述】:

假设我有 2 个控制器,TopicsControllerPostsController

对于每个控制器,我有几个视图(索引和详细信息)。

主题(索引) 视图继承 System.Web.Mvc.ViewPage<IEnumerable<MessageBoard.Models.Topic>>

Topic (Details) 视图继承了System.Web.Mvc.ViewPage<MessageBoard.Models.TopicFormViewModel>
我正在使用 TopicFormViewModel,因为我正在与模型一起发送额外的数据。 p>

Post (Details) 视图仅继承 System.Web.Mvc.ViewPage<MessageBoard.Models.Post>

现在,我创建了一个局部视图 (CreatePost.ascx),它(显然 :p)用于创建新帖子。我希望能够在您在上面看到的所有视图上重复使用此控件。

更新
我尝试使用 Topics/Index.aspx 视图中的<% Html.RenderPartial("New"); %> 渲染部分视图,但这会导致异常

传入字典的模型项的类型为“System.Data.Linq.Table`1[MessageBoard.Models.Topic]”,但此字典需要“MessageBoard.Models.Post”类型的模型项。

现在的问题是我的部分视图 (CreatePost.ascx) 接受 System.Web.Mvc.ViewUserControl<MessageBoard.Models.Post>,我不确定如何从上面的所有视图中传递它.

我也不确定如何将 .ascx 值提交到某个 URL(即 /Topics/1/CreatePost),我如何告诉提交按钮发布到该 URL?

提前致谢,
马尔科

【问题讨论】:

  • 呃,为什么要投反对票?似乎有人在开玩笑,并否决了我的问题。
  • CreatePost 上面有哪些表单元素?为什么是Post 类型?不是从头开始创建一个帖子,因此帖子还不存在吗?
  • @p.campbell - 你是对的。我想要传递模型的原因实际上是每个帖子都与一个主题相关联,我需要 ID 以便我可以在正确的位置创建帖子。我现在已经使用 ViewData 来做到这一点,而且它似乎工作得很好。我唯一担心的是必须从每个在页面上具有 Add Post 表单的控制器 Action 传递 ViewData,但我可以处理这个问题。这是我的第一个项目,所以还在学习:)

标签: c# asp.net-mvc viewmodel


【解决方案1】:

Ciao 马尔科,

现在的问题是我的部分 视图 (CreatePost.ascx) 接受一个 System.Web.Mvc.ViewUserControl 我不知道如何从 以上都是我的观点。

我不确定我是否理解“如何从我上面的所有视图中传递它”是什么意思,但我相信你不必从你的视图中传递 Post 的实例。发生的情况是,从您的视图中,您将调用创建 Post 模型对象的控制器操作,然后将其绑定到 CreatePost.ascx 部分。

我也不确定如何提交 .ascx 值到某个 URL(即 /Topics/1/CreatePost),我怎么知道 要发布到该 URL 的提交按钮?

你有两个选择:

在您的 CreatePost.ascx 部分中,您可能正在使用一个表单。

<% using (Html.BeginForm("action", "controller", FormMethod.Post, new {} )) { %>

如果您按照我展示的方式使用,您可以将第一个和第二个参数分别更改为将阻止您提交的 Action 和 Controller 的名称。

第二个选项是使用 jQuery。只需为您的表单设置一个 ID,然后

$("#myForm").submit(function(event) {
    //post an ajax request to the server
});

希望这会有所帮助!

附:为了能够重用您的 CreatePost.ascx 部分,请将其放在共享视图文件夹(您的母版页所在的位置)中。

【讨论】:

  • 嗨@Lorenzo,感谢BeginForm 的提示,我不知道它接受参数,所以我现在已经解决了这个问题。干杯!关于其他问题,请看我的更新。
  • @Marko:如果您在 MyObject 类的强类型视图中执行 RenderPartial,框架将尝试将该对象实例传递给 RenderPartial 方法。但是你的部分是强类型到另一个对象......你应该创建一个 Post 模型的实例,然后做&lt;% Html.RenderPartial("CreatePost", myPostInstance); %&gt;
  • 无论如何我想警告你,在视图中创建对象实例不是正确的方法......
  • 请参阅我对上述@p.campbell 的回复。我现在会接受你的回答,为帮助欢呼!
  • @Marko:好的! ViewData 是处理这项工作的好方法。我发布了另一个描述另一种方法的答案。很高兴知道这在某种程度上有所帮助
【解决方案2】:

关于重用不在同一视图文件夹中的局部视图,请使用以下内容并传入所需的模型,或者您可以为其定义自定义路由。

<% html.RenderPartial("~/Views/<ControllerName>/<PartialViewName>.ascx", <model>);

【讨论】:

  • 嘿@Dien,我的问题与将模型传递给 RenderPartial 有关,而不是与查找 Partial View 本身有关 :)
  • 当然,没问题。我确定您知道这一点,但您可以将模型作为参数传递给局部视图。
【解决方案3】:

@马可

另一种方法是在 PostController 中添加一个 Action,如下所示:

[HttpGet]
public ActionResult CreatePost( int topicId ) {
    PostModel pm = _manager.CreateDefaultPost();
    pm.TopicID = id;
    return PartialView( "CreatePost", pm );
}

然后,无论您想在哪里创建帖子,您都可以简单地调用此操作,为您的新帖子返回强类型视图。

即使您通过网络 IMO 进行补充 http 调用,此解决方案也具有将新 Post 的初始化代码集中到一个地方的优势。

从“观点”视图中,当用户按下“新帖子”按钮然后将收到的标记注入模式对话框或您喜欢的位置时,可以完成对操作的调用当前页面。

希望对你有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 2017-07-19
    • 2011-07-27
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    相关资源
    最近更新 更多