我正在尝试使用一般主页,根据传递给控件的参数,将显示不同的内容(模块)。
例如,用户可以从菜单中选择肯塔基州,肯塔基州的ID是1.家庭控制器获取id(1)并确定可能的模块 state(一个简单的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基本上就像“公告”,我可以创建一个announcements.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);
}
这将是正确的局部视图并将其传递给正确的模型。
答案 0 :(得分: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);
在相应的“Shared”文件夹中为每个Type
模块创建部分视图。 (在没有创建它们的情况下运行它,它会向你显示一个异常,其中包含它正在寻找它们的位置)。
答案 1 :(得分: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
}
我意识到有更简单的方法来编码控制器,我计划重构,但这个骨架应该提供解决我发布的问题的基础知识。