65.9K
CodeProject 正在变化。 阅读更多。
Home

MVC 的 JavaScript 组织

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (8投票s)

2011年1月10日

CPOL

2分钟阅读

viewsIcon

28312

一种快速简便的方法,用于组织为特定视图执行的脚本。

引言

在构建应用程序架构时,代码组织是我最头疼的问题之一。我目前有一个使用 ASP.NET MVC 2 构建的应用程序,使用了 IOC、依赖注入以及从业务层到后端的多层抽象。

但是,我发现当一切都完成后……有大量的 .js 文件用于执行所有的 UI 验证、呈现、AJAX 调用等等。大多数脚本都位于单独的文件中,但也有很多在视图中。调试并将这些脚本交给下一个开发人员变得具有挑战性。

目标是重构组织结构,并允许逐步迁移到更好地理解哪些脚本在何处执行以及脚本文件的哪个部分负责哪个视图。解决方案 - ScriptViewPage.cs

ScriptViewPage

ScriptViewPage 类继承自 System.Web.Mvc.ViewPage,并在实例化时,为 PreLoad 事件添加一个事件处理程序。因此,当视图渲染或预渲染时,该事件被触发,并且 ScriptViewPage 现在处理并确定正在执行的视图,并尝试找到与之关联的脚本文件。

namespace System.Web.Mvc {     
    public class ScriptViewPage : ViewPage     
    {         
        public ScriptViewPage() 
            : base()         
        { 
                this.PreLoad += new EventHandler(_PreLoad);         
        }

在处理程序中,我们深入 ViewContext.RouteData 以确定控制器和视图,并格式化 .js 脚本文件名。

string viewScriptPath = string.Format("~/ViewScripts/{0}/{1}.js", 
                        ViewContext.RouteData.Values["Controller"], 
ViewContext.RouteData.Values["Action"]);

测试文件是否存在,并使用 TagBuilder 创建脚本标签,如果控件存在,则将 Literal 控件的文本设置为母版页/视图上的文本。

if (System.IO.File.Exists(MapPath(viewScriptPath)))
{
   var scr = new TagBuilder("script");
   scr.Attributes.Add("type", "text/javascript");
   scr.Attributes.Add("src", ResolveClientUrl(viewScriptPath));

   Control ctrl = Page.Master.FindControl("viewScript");
   if (ctrl != null)
     ((Literal)ctrl).Text = scr.ToString(TagRenderMode.Normal);

}

这是完整的类代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace System.Web.Mvc
{
    public class ScriptViewPage : ViewPage
    {
        public ScriptViewPage()
            : base()
        {
            this.PreLoad += new EventHandler(_PreLoad);
        }

        void _PreLoad(object sender, EventArgs e)
        {
            string viewScriptPath = 
              string.Format("~/ViewScripts/{0}/{1}.js", 
              ViewContext.RouteData.Values["Controller"], 
              ViewContext.RouteData.Values["Action"]);

            if (System.IO.File.Exists(MapPath(viewScriptPath)))
            {
                var scr = new TagBuilder("script");
                scr.Attributes.Add("type", "text/javascript");
                scr.Attributes.Add("src", ResolveClientUrl(viewScriptPath));


                Control ctrl = Page.Master.FindControl("viewScript");
                if (ctrl != null)
                    ((Literal)ctrl).Text = scr.ToString(TagRenderMode.Normal);

            }
        }
    }
}

您需要确保的是,.js 文件与您的视图同名。

实现

我需要一种方法来逐步重构现有代码,同时允许将新的脚本组织用于添加到应用程序中的所有新视图/脚本。这是我采取的方向。

  • 在 Web 应用程序的根目录下添加一个名为“ViewScripts”的新文件夹。
  • 复制“Views”文件夹中存在的文件夹结构。
  • 编辑 Site.Master,并在关闭 body 标签的模板底部添加一个 Literal 控件,并设置 ID="viewScript"
  • 在您的视图中,不要从 System.Web.Mvc.ViewPage 继承,而是更改为 System.Web.Mvc.ScriptViewPage

关注点

可能还有其他方法可以完成相同的任务,但这是为了避免不得不重构当前应用程序,并能够组织和继续前进,并为现有脚本提供一个重构结构而采取的最简单的方法。请享受。

© . All rights reserved.