代码之家  ›  专栏  ›  技术社区  ›  eKek0

如何以面向对象的方式显示不同的视图部分

  •  1
  • eKek0  · 技术社区  · 15 年前

    我不知道如何以面向对象的方式来实现这一点。我认为这可以通过继承来实现,但我不知道如何在视图中实现继承。

    <% if (User has some security level) { %>
       <span>show this info</span>
    <% } %>
    

    但这味道不好。事实上,我不知道如何使用面向对象的原则或设计来完成这项任务。

    我认为这是一项共同的任务,因此我认为有一种模式可以完成这项任务。例如,Stackoverflow在为发布问题(或答案或评论)的用户显示某些选项(编辑、删除等)并向其他人隐藏相同选项时会执行此操作。

    4 回复  |  直到 15 年前
        1
  •  0
  •   tvanfosson    15 年前

    根据您所做工作的复杂性,if语句路由可能就足够了。如果没有,那么您可以考虑使用局部视图,并编写一个HtmlHelper扩展,允许您基于特定角色呈现局部视图。它可能看起来像这样:

    <% Html.RenderPartialWithRole( "AdminSection",
                                   Model,
                                   ViewData,
                                   User,
                                   "Administrator",
                                   null ) %>
    
    
    public static void RenderPartialWithRole( this HtmlHelper helper,
                                              string partialName,
                                              object model,
                                              ViewDataDictionary viewData,
                                              IPrincipal user,
                                              string role,
                                              object htmlAttributes )
    {
         if (user != null && !string.IsNullOrEmpty(role) && user.IsInRole(role))
         {
              helper.RenderPartial( partialName, model, viewData, htmlAttributes );
         }
    }
    
        2
  •  0
  •   Carlton Jenke    15 年前

        3
  •  0
  •   Carlton Jenke    15 年前

    您可以将所有的部分放在partials中,并构建视图以包含不同权限级别可用的部分。因此,一个用于管理员,一个用于每个级别。然后,控制器具有决定使用哪个视图的逻辑。因此,任何OO部分都将位于控制器中,而不是视图中。

        4
  •  0
  •   keithm    15 年前

    这不是一种面向对象的方法,但它是相关的。这个问题有趣的部分是如何利用if语句。摆脱if或case的常用方法是使用条件和效果的查找表。还有其他技术也使用同样的思想,比如数据导向编程( http://en.wikipedia.org/wiki/Data-directed___programming )和调度表( http://en.wikipedia.org/wiki/Dispatch_table )。许多语言实现使用类型分派表来实现虚拟方法调用。

    假设局部视图可以解决此问题,则查找表可以是对的列表。该对的第一个元素是要对照当前用户检查的角色名。该对的第二个元素是角色检查成功时要呈现的部分视图的名称。

    我们在控制器(或任何地方)中初始化表并将其分配给ViewData,然后使用Html.RenderViewByRole选择并呈现正确的局部视图:

    <% Html.RenderPartialByRole(User, (List<Dispatch>)ViewData["rolePartial"]); %>
    
    public static class MyHelper {
        public static void RenderPartialByRole(this HtmlHelper helper, IPrincipal user, List<Dispatch> rolePartial) {
            foreach (Dispatch d in rolePartial) {
                if (d.CheckRole(user)) {
                    helper.RenderPartial(d.PartialName);
                    break;
                }
            }
        }
    }
    
    public class Dispatch {
        string _roleName;
        string _partialName;
    
        public Dispatch(string roleName, string partialName) {
            _roleName = roleName;
            _partialName = partialName;
        }
        public bool CheckRole(IPrincipal user) {
            return user.IsInRole(_roleName);
        }
        public string PartialName {
            get { return _partialName; }
        }
    }
    
    public class HomeController : Controller {
    
        List<Dispatch> rolePartial = new List<Dispatch>();
        private void InitTable() {
            rolePartial.Add(new Dispatch("admin", "adminPartial"));
            rolePartial.Add(new Dispatch("report", "reportPartial"));
            rolePartial.Add(new Dispatch("guest", "guestPartial"));
        }
    
        public HomeController() {
            InitTable();
        }
    
        public ActionResult Index() {
            ViewData["rolePartial"] = rolePartial;
            return View();
        }
    }