【问题标题】:Many models to view with many partial views许多模型以许多局部视图查看
【发布时间】:2012-05-26 21:39:56
【问题描述】:

我有一个包含许多部分视图的视图,我需要将匹配模型传递给每个视图。

我已经找到了 2 种方法来做到这一点,但我不知道真正的方法应该是什么。

  1. 我想创建一个包含所有模型作为属性的大类,然后我可以将模型发送到每个局部视图。问题是它是硬类型的,如果我需要传递不同的模型组合,它就不适合了。

  2. 我想到的另一种方法是在每个模型中都有一个方法,为每个局部视图提供模型(GetMenuBar() 等)。

这样做的正确方法是什么?

【问题讨论】:

  • 你能解释一下你的意思:“the problem is that its hard typed, and if i need to pass a diffrent combination of models it wont fit.”吗?
  • 这听起来像是一个很好的接口隔离候选者——让模型对象为它所驱动的每个部分实现一个接口。
  • @arootbeer 我同意,这正是我在当前项目中使用的。以及 VM 的抽象和/或继承类
  • Yakimych - 我认为它'硬编码'为每个大视图创建许多模型作为属性,因为它使每个视图都专用于特定部分视图的特定视图,但现在我明白这是完全正常的。 arootbeer - 拥有具有“GetX”/“GetY”方法的接口是有意义的。我想知道除了这种方法(GetArticles/GetUsers)之外,该接口是否还有其他用途。我不知道在模型类中创建逻辑是否合法。 AlfalfaStrange - 您是否在模型类中插入了实际上具有内部逻辑且不仅用作 DAL 的方法?
  • @Aviran 不,我的模型中没有任何逻辑,我在控制器级别处理数据收集,也就是说我的控制器操作中的方法使用我的 BLL 并且使用我的 DAL .所以在我的控制器中,我将有 model.Entity = entityInstance.GetByID(id);返回该类的一个实例。该实例调用 DAL 以从数据库中获取数据

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


【解决方案1】:

我的建议是选择选项 1。我将它与我的所有主视图/多部分视图场景一起使用。由于每个部分都有自己的 ViewModel,因此易于维护。它使整个事物保持整洁

我使用完全相同的设置,如下所示:

public class MainViewModel {

    public Partial1ViewModel Partial1 [ get; set; }
    public Partial2ViewModel Partial2 [ get; set; }
    public Partial3ViewModel Partial3 { get; set; }
    public Partial4ViewModel Partial4 { get; set; }

    public MainViewModel() {}

    public MainViewModel() {
        Partial1 = new Partial1ViewModel();
        Partial2 = new Partial2ViewModel();
        Partial3 = new Partial3ViewModel();
        Partial4 = new Partial4ViewModel();
    }
}

每个PartialViewXViewModel 都是它自己的 ViewModel,如果需要,可以在另一个视图中重用。

渲染的 Action 可能如下所示:

public ActionResult Index {
    var model = new MainViewModel();
    return View(model);
}

你的观点

@model MainViewModel

<div>
    {@Html.RenderPartial("PartialOne", Model.Partial1)}
</div>


<div>
    {@Html.RenderPartial("PartialTwo", Model.Partial2)}
</div>


<div>
    {@Html.RenderPartial("PartialThree", Model.Partial3)}
</div>


<div>
    {@Html.RenderPartial("PartialFour", Model.Partial4)}
</div>

为每个 PartialX 定义 UI,例如:

@model Partial1ViewModel

//view html here

现在,每个 Partial view html 和他们使用的每个模型都可以在任何地方使用。

现在最重要的是,如果您有一个只需要其中两个的页面,您只需创建一个新的 ViewModel 来表示该特定视图,如下所示:

public class OtherMainViewModel {

    public Partial2ViewModel Partial2 [ get; set; }
    public Partial4ViewModel Partial4 { get; set; }

    public OtherMainViewModel() {}

    public OtherMainViewModel() {
        Partial2 = new Partial2ViewModel();
        Partial4 = new Partial4ViewModel();
    }
}

然后像这样在另一个视图中使用它:

public ActionResult SomeOtherAction {
    var model = new OtherMainViewModel();
    return View(model);
}

这是完全可以接受的,也是 MVC 中的首选设计策略,让 ViewModel 专门表示视图需要什么,并且只表示它需要什么。

您可能希望使用不同的方法来填充模型。这里的大多数人会推荐使用 Automapper。无论哪种方式,上面只是在 MainViewModel 的构造函数中初始化 PartialViewXModels。如果您使用数据库中的数据填充这些模型,则不一定是您的情况。你会想要你自己的策略。这可以在这里工作:

public ActionResult Index {
    var model = new MainViewModel();
    model.Partial1 = GetPartial1Data(); // this method would return Partial1ViewModel instance
    model.Partial2 = GetPartial2Data(); // same as above for Partial2ViewModel
    ...
    return View(model);
}

这一切都只是让您开始设计,您可以根据自己的内心进行调整:-)

【讨论】:

  • 您为每个页面创建“MainViewModel”?例如 - “MainPageViewModel”、“ArticlesPageViewModel”等等,或者你在每个控件/页面中都传递相同的模型,你使用你需要的?第二个选项我可以理解你可以使用任何你想要的属性,它不是标题?
  • 如果您有多个页面使用所有这些部分,那么是的,您使用该页面所代表的 ViewModel。如果您有一个不需要所有这些部分的页面,那么您将创建一个不同的 ViewModel,如我最后的答案更新中所示
  • 谢谢,我学到了很多关于 MVC 设计视角的知识 :)
  • 我还没有测试过这个解决方案,但是我可以看到当同一个 ViewModel 被使用两次时会出现问题,并且您需要在每个字段前添加前缀。例如,您在同一页面上呈现了 2 个 AddressViewModel 类。一个是邮寄地址,一个是街道地址。两个 ViewModel 不能具有相同的 ID,因此您必须想出一些方法来将这些前缀添加到每个字段。 EditorFor 会处理这个问题,但你最终会得到“#MainViewModel_Partial1_ZipCode”。然而,这只是使用 JavaScript 做任何事情时的一个大问题。
猜你喜欢
  • 1970-01-01
  • 2018-07-16
  • 1970-01-01
  • 1970-01-01
  • 2019-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多