【问题标题】:Nested ViewModels / Partial View problems in MVCMVC 中的嵌套视图模型/部分视图问题
【发布时间】:2014-11-04 17:16:58
【问题描述】:

我有两个视图:一个局部视图,以及一个使用@Html.RenderPartial("_PartialView") 封装局部视图的视图。每个都有自己的 ViewModel:

public class PartialViewModel 
{
    // properties, etc.
}

public class MainViewModel 
{
    public PartialViewModel p { get; set; }
    // properties, etc.
}

加载第二个视图(使用 MainViewModel 的视图)时出现字典错误,因为此视图及其封装的局部视图使用两个不同的 ViewModel。我不能让他们使用相同的 ViewModel,因为局部视图在许多其他不同的视图中呈现。

要清楚,both of these views contain forms,部分视图表示表单之间的所有共享字段。鉴于此,我是否有任何选择,或者我只是试图做一些不符合 MVC 设计约束的事情?

【问题讨论】:

    标签: c# asp.net-mvc mvvm


    【解决方案1】:

    你会想要设计这个有点不同。主视图会有一个模型——我们称之为MainModel,部分视图可以有一个模型——我们称之为PartialModel

    public class PartialModel 
    {
       /// props
    }
    
    public class MainViewModel 
    {
        public PartialModel Partial { get; set; }
        // properties, etc.
    
        // per comments in other answer you may want something like this
        public MainViewModel()
        {
          Partial = new PartialModel();
        }
    }
    

    那么你的主视图就会有

    @model MainViewModel
    

    然后在主视图的中间你有类似的东西

    @{ Html.RenderPartial("myPartialView", Model.Partial); }
    

    注意 Html.RenderPartial 周围的大括号。它们是必需的,因为 RenderPartial 返回无效。

    当您渲染局部视图时,您还可以将模型传递给它,如果设计正确,那么局部需要的模型已经可以从主视图的模型中访问

    【讨论】:

    • 我想这就是我所缺少的——@Html.RenderPartial 的第二个参数。谢谢。
    • @alex,更多信息,如果你在使用RenderPartial时没有指定模型,默认情况下它将使用主视图ViewDataDictionary,所以它将MainViewModel传递给部分,但是因为部分期望PartialViewModel 你会得到错误。
    【解决方案2】:

    您可以这样做,但您需要在控制器中声明一个新的 MainViewModel 并为其 PartialViewModel 分配一个新的 PartialViewModel。

    例如:

    public class Controller {
        public ActionResult Index(){
            var mainViewModel = new MainViewModel { PartialViewModel = new PartialViewModel() };
            return View(mainViewModel);
        }
    }
    

    现在,我会将这些模型的创建委托给工厂,但在您开始重构之前,这更高级且没有必要。

    【讨论】:

    • 为什么要投票?当你 RenderPartial() 你没有调用控制器时,你只是直接渲染一个视图,模型必须从视图传递。您必须在我的回答中指定哪个模型。有些设计模式总是使用相同的视图模型,而且它们很大,如果是这种情况,那么您可以只渲染部分而不指定模型,它将使用父视图中的相同模型
    • @ScottSelby 它最有可能被赞成,因为如果您尝试访问尚未初始化的子视图模型的属性,您将收到 NullReferenceException,因为它不会默认初始化。
    • 不 - 只要主模型初始化它,它就会。当您执行 RedirectToAction("action", "controller") 时,所有这些代码所做的只是提供帮助,但与 @Html.RenderPartial 完全无关
    • "只要主模型初始化就可以"?所以换句话说,默认情况下它不会这样做,OP 需要这样做,否则页面会崩溃?在这种情况下,我看到您的回答存在问题,因为它没有涵盖这一点。他已经将您标记为答案,我的答案将帮助未能初始化其子视图模型的人。你需要重新评估你投反对票的原因,因为有人清楚地发现我的贡献很有价值,而你只是无缘无故地投反对票。
    • 是的 - 我明白你的意思,这可以帮助有类似情况的人。这只是当一个动作被调用并且该动作调用一个视图时,OP问题是关于什么时候直接调用一个视图。我相信.Net框架实际上会初始化一个新的默认版本的对象并防止错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    相关资源
    最近更新 更多