rah*_*kim 5 model-view-controller model renderpartial partial-views asp.net-mvc-3
我试图有一个通用的主页,根据传递给控件的参数,将显示不同的内容(模块).
例如,用户可以从菜单中选择肯塔基州,肯塔基州的ID是1.家庭控制器获取id(1)并确定该状态的可能模块(简单的数据库调用).也许有一个公告模块和国家的联系人模块.公告模块可能有几个项目,但它只有一个模块.每种类型的模块都会有部分视图.
这是我的基本设置.
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 ...
}
Run Code Online (Sandbox Code Playgroud)
在我的家庭控制器......
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试了几种不同的模型来返回,但我总是遇到一些限制.如果我将menuitemmodules传递给我的Item.aspx,那么我可以这样做:
foreach (var mod in Model)
{
Html.RenderPartial(mod.Src, a); //needs an announcement object though
}
Run Code Online (Sandbox Code Playgroud)
这使它有点动态,因为我有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; }
}
Run Code Online (Sandbox Code Playgroud)
如果我将该模型传递给Item.aspx,我可以做这样的事情(但我必须做错事,因为看起来不对劲.)
foreach (var mod in Model)
{
if (mod.announcements.Count > 0)
{
Html.RenderPartial("Announcements", mod.announcements);
}
}
Run Code Online (Sandbox Code Playgroud)
再次,可扩展性将困扰我.我想在项目页面上有这样的东西:
foreach (var mod in Model)
{
Html.RenderPartial(mod.Src, mod);
}
Run Code Online (Sandbox Code Playgroud)
这将是正确的局部视图并将其传递给正确的模型.
经过一个多星期的折腾,我终于弄清楚 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 ...
}
Run Code Online (Sandbox Code Playgroud)
我还添加了另一个类:
public class AnnouncementModule : MenuItemModule
{
private IList<Announcements> _Announcements;
//get set prop
}
Run Code Online (Sandbox Code Playgroud)
...我为视图创建了一个模型
public class HomeItemViewModel
{
public MenuItemModule[] MenuItemModules { get; set; } //collection of menuitemmodules
}
Run Code Online (Sandbox Code Playgroud)
在我的家庭控制器中...
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);
Run Code Online (Sandbox Code Playgroud)
然后我按照建议在视图中使用 DisplayFor 。该视图被强类型化为 HomeItemViewModel。
<%: Html.DisplayFor(m => m.MenuItemModules) %>
Run Code Online (Sandbox Code Playgroud)
这会迭代集合并根据类型调用该模板。在此示例中,它调用AnnouncementModule.ascx,它是强类型化的AnnouncementModule。
foreach (var a in Model.Announcements)
{
//a.Description will give us the description of the announcement
}
Run Code Online (Sandbox Code Playgroud)
我意识到有更灵活的方法来编码控制器,并且我计划进行重构,但是这个框架应该提供解决我发布的问题的基础知识。
| 归档时间: |
|
| 查看次数: |
4017 次 |
| 最近记录: |