5

我试图有一个通用主页,根据传递给控件的参数,将显示不同的内容(模块)。

例如,用户可以从菜单中选择 Kentucky,Kentucky 的 id 为 1。家庭控制器获取 id (1) 并确定该状态的可能模块(一个简单的 db 调用)。也许有一个公告模块和状态的联系人模块。一个公告模块可以有多个项目,但它只有一个模块。每种类型的模块都会有一个局部视图。

这是我的基本设置。

public interface IModuleRepository
{
    IList<MenuItemModule> GetMenuItemModules(int menuItem);
    IList<Announcements> GetAnnouncements(int modID);
    IList<News> GetNews(int modID);
    IList<Contacts> GetContacts(int modID);
}



//business object
public class MenuItemModule
{

    private int _MenuItemID;
    private int _ModuleID;
    private int _ModuleDefID;
    private string _Src;
    private int _ModuleOrder;

//get, set properties for these...

}

//announcements entity
public class Announcements
{
    private int _ID = -1;
    private int _MenuItemID = -1;
    private int _ModuleID = -1;
    private string _Description = string.Empty;

//get set props ...
}

在我的家庭控制器中...

public class HomeController : Controller
{


    private IModuleRepository modRepository;

    public HomeController(IModuleRepository modRepository)
    {
        this.modRepository = modRepository;
    }


    public ViewResult Item(string ItemID)
    {

        //returns a list of menuitemmodules for the page.  This gives me the Src or name of each
        //module on the page, i.e. Announcements, news, contacts, etc. 
        var modules = modRepository.GetMenuItemModules(Convert.ToInt32(ItemID)); 


        return View(modules);

   }

}

我尝试了几种不同的模型来返回,但我总是遇到一些限制。如果我将 menuitemmodules 传递给我的 Item.aspx,那么我可以执行以下操作:

   foreach (var mod in Model)           
   {               
        Html.RenderPartial(mod.Src, a);      //needs an announcement object though    
   } 

这使它有点动态,因为我有 Src,它基本上类似于“公告”,我可以创建一个公告.ascx 部分来处理模块。但是我发现传递我的 menuitemmodule 和通知实体也很困难。

我还搞砸了传递一个更复杂的对象,然后测试每个带有 If 语句的 Src。随着我增加应用程序中可能模块的数量,这将使未来的扩展变得困难。

我该如何解决我的问题?我希望我提供了足够的信息。我喜欢这里的基本想法 - http://www.mikesdotnetting.com/Article/105/ASP.NET-MVC-Partial-Views-and-Strongly-Typed-Custom-ViewModels但这似乎只适用于静态模块页面。

我确实尝试了一个名为 ModuleViewModel 的复合视图模型。这是尝试:

public class ModuleViewModel
{
    public IList<Announcements> announcements { get; set; }
    public IList<MenuItemModule> mods { get; set; }

}

如果我将该模型传递给 Item.aspx,我可以做这样的事情(但我一定做错了什么,因为某些事情看起来不正确。)

   foreach (var mod in Model)           
   {

       if (mod.announcements.Count > 0)
       {
           Html.RenderPartial("Announcements", mod.announcements);
       }


   } 

再一次,可扩展性将困扰我。我想在项目页面上有这样的东西:

   foreach (var mod in Model)           
   {

           Html.RenderPartial(mod.Src, mod);          

   } 

那将是正确的局部视图并将其传递给正确的模型。

4

2 回答 2

0

创建从通用模块基类派生的模块类:

public class AnnouncementsModule : Module
{
}

public class ContactsModule : Module
{
}

在控制器中:

创建各种模块并将它们放入您的整体视图模块中(这里它有一个名为 Modules 的属性,它是一个数组Module

var viewModel = new ComplexViewModel 
                { 
                    Modules = new [] 
                    { 
                       new ContactsModule(), 
                       new AnnouncementsModule() 
                    }
                 };
return View(viewModule);

鉴于:

@Html.DisplayFor(x => x.Modules);

Type在适当的“共享”文件夹中为每个模块创建部分视图。(在不创建它们的情况下运行它,它会向您显示它正在寻找它们的位置的异常)。

于 2013-04-25T17:59:50.280 回答
0

在搞砸了一个多星期之后,我终于设法弄清楚 MVC 如何动态地做我想做的事。我决定为 MVC 新手发布我的解决方案。希望以下内容能够消除我的误解(尽管在我对 MVC 的理解中,我不能说这是最好的方法。)

为了清楚起见,我将包括以前的代码片段和修改:

 public interface IModuleRepository
 {
      IList<MenuItemModule> GetMenuItemModules(int menuItem);
      IList<Announcements> GetAnnouncements(int modID);
      IList<News> GetNews(int modID);
      IList<Contacts> GetContacts(int modID);
 }



//business object
public class MenuItemModule
{

    private int _MenuItemID;
    private int _ModuleID;
    private int _ModuleDefID;
    private string _Src;
    private int _ModuleOrder;

//get, set properties for these...

}

//announcements entity
public class Announcements  : MenuItemModule
{
    private int _ID = -1;
    private string _Description = string.Empty;

//get set props ...
}

我还添加了另一个类:

public class AnnouncementModule : MenuItemModule
{
    private IList<Announcements> _Announcements;
    //get set prop
}

...我为视图创建了一个模型

public class HomeItemViewModel
{
    public MenuItemModule[] MenuItemModules { get; set; } //collection of menuitemmodules
}

在我的家庭控制器中...

    var menuItemModules = modRepository.GetMenuItemModules(ItemID);

    if (menuItemModules.Count > 0)
    {
        AnnouncementModule aMod;
        MenuItemModule[] mods = new MenuItemModule[menuItemModules.Count()];

        int i = 0;

        //loop through each MenuItemModule assign to the appropriate model
        foreach (MenuItemModule mod in menuItemModules)
        {
            if (mod.Src == "Announcements")
            {
                aMod = new AnnouncementModule();
                aMod.Announcements = modRepository.GetAnnouncements(mod.ModuleID);

                //now add this to the menuitemmodule collection
                mods[i] = aMod;
            }

            if (mod.Src == "Contacts")
            {
                //...
            }

            i++;
        }

    }


    var viewModel = new HomeItemViewModel
    {
        MenuItemModules = mods
    };

    return View(viewModel);

然后我使用了在视图中使用 DisplayFor 的建议。视图被强类型化为 HomeItemViewModel。

<%: Html.DisplayFor(m => m.MenuItemModules) %>

这将遍历集合并根据类型调用该模板。在这个例子中,它调用 AnnouncementModule.ascx,它是强类型的 AnnouncementModule。

foreach (var a in Model.Announcements)
{
    //a.Description will give us the description of the announcement
}

我意识到有更巧妙的方法来编写控制器,并且我计划重构,但是这个框架应该提供解决我发布的问题的基础知识。

于 2013-05-09T15:55:44.887 回答