代码之家  ›  专栏  ›  技术社区  ›  Erv Walter

如何封装ASP的可重用“控件”。NET MVC 3+Razor视图

  •  4
  • Erv Walter  · 技术社区  · 14 年前

    我正在寻找如何创建一个可重用的“控件”以用于几个MVC 3视图的最佳实践。我可以创建一个Html助手扩展方法(通过编程或使用razor中的声明性助手),也可以创建一个局部视图。

    在我的例子中,诀窍在于我需要做的不仅仅是在视图调用helper/partial的位置转储一些HTML。除了在该位置放置一些HTML标记外,我还需要添加一些javascript代码以使其正常工作。通常,我会把这个代码放在页面的其他地方(例如底部)。这当然不是必须的。另外,请注意,javascript不是特定于控件实例的。换句话说,可以编写javascript,在页面上查找控件HTMl标记的所有实例,并用适当的事件“激活”它,等等。

    我考虑过几种可能性。

    1. 让助手/部分转储HTML和 <script> 在它被称为的地方贴上标签。这似乎是个坏主意,因为这意味着控件每页只能使用一次。
    2. 有两个帮手。一个用于输出HTML标记,另一个用于输出javascript。第二个脚本只会被调用一次,并且会从页面底部调用,以便脚本最终位于正确的位置。如果我发明了第二个这样的控件,我将有4个助手(2个用于HTML,2个用于Javascript)。
    3. 发明一种脚本管理器,控件可以注册javascript。scriptmanager会在页面底部添加一些帮助程序,并为所有注册了脚本片段的控件转储javascript。对scriptmanager助手的调用可能在_布局中。cshtml,这样它就会自动出现在任何需要它的页面上。当一个页面不需要它时,它什么也做不了。我想这看起来不太像MVC。
    4. 只需要有一个助手,可以吐出HTML,然后将javascript添加到站点。每个页面都包含js。如果javascript在页面上找不到任何相关的标记(标记将有一个带有特定类的包装器元素),它将足够聪明,不会做任何事情。但是,在所有页面上搜索标记会有开销,包括没有这些控件的页面。
    5. 与#4相同,但将javascript放在自己的脚本中。js文件,并仅在使用该控件的页面上包含它。这对于不使用该控件的页面更有效,但这是一个额外的功能。js文件和相关的HTTP请求。

    我倾向于#4,但这是一个解决了的问题吗?有更好的第六种选择吗?

    2 回复  |  直到 14 年前
        1
  •  2
  •   TimLeung    14 年前

    我的公司正在使用MVCContrib portable areas将代码打包到一个DLL中,用于可重用的“组件”

    每个组件都可以通过扩展方法调用。例如:

    Html.Components().ShowPoll();
    

    在这些组件中,有一种方法可以注册多个作为嵌入式资源的css/js文件。我们的主站点将提取资源文件,并在提供服务之前对其进行缩小+合并。

    组件还将注册文档期间调用的任何页面事件。JQuery的OnReady事件。这允许每个组件都是小型站点,具有独立的功能和自己的路线、模型和视图。

    在整个网站上,所有组件都提供相同的zip-up JS。一个原因是文件将被缓存,另一个原因是消除了确定页面上有哪些组件及其所需资源的复杂性。

    如果您想了解有关此设置的更多信息,请告诉我。

        2
  •  0
  •   Joey Morgan    13 年前

    我用一个布局页面管理这个问题,该页面有一个名为jsCode的部分。

    @RenderSection("jsCode",false)
    

    然后,当我需要它时,我会在内容页中创建:

    @section jsCode
    {
    <script type="text/JavaScript" src="myJsCode.js"></script>
    }
    

    您还可以创建一个助手,它可以输出特定页面所需的脚本,并以这种方式对其进行封装,如下所示:

     @helper MyJSFunction(string FunctionName){
    
            switch(FunctionName)
            {
                case "firstFN":
            <text>
        <script type="text/JavaScript">
            function SaySomethingSilly()
            {
                var sillySaying="We are the knights who say 'ni'!";
                alert(sillySaying);
            }
            </script>
            </text>
    
            break;
            case "secondFN":
            <text>
            <script type="text/JavaScript">
                    function SaySomethingElse()
            {   var sillySaying="We are looking for a shrubbery...";
                alert(sillySaying);
            }   
            </script>
            </text>
        break;
        }
        }
    

    然后我的内容页(假设我想要两个功能)如下所示:

    @{
    Page.Title="Using helpers to create scripts";}
    @section jsCode
    {
    @JSHelpers.MyJSFunction("firstFN")
    @JSHelpers.MyJSFunction("secondFN")
    }
    <p>It works!</p>
    

    产生了以下结果:

    <!DOCTYPE html>
    
    <html lang="en">
        <head>
            <meta charset="utf-8" />
            <title>Using helpers to create scripts</title>
    
    
    <script type="text/JavaScript">
        function SaySomethingSilly()
        {
            var sillySaying="We are the knights who say 'ni'!";
            alert(sillySaying);
        }
        </script>
    
    
        <script type="text/JavaScript">
                function SaySomethingElse()
        {   var sillySaying="We are looking for a shrubbery...";
            alert(sillySaying);
        }   
        </script>
    
    
    
        </head>
        <body>
    
    <p>It works!</p>
        </body>
    </html>
    

    现在,如果你想变得超级高效(尽管我想到了其他词),你可以给函数传递一个JSON数组或字典,甚至是一个字符串数组,其中包含你想要使用的脚本的名称,或者要导入的JavaScript,或者其他什么,只需对助手进行一次调用。我认为,无论如何加载helper函数的返回值,单独的调用都更容易维护,因为您可以一目了然地看到在给定页面上使用的脚本,消除或添加一个脚本只是简单的一行更改,而不是更改数组的一个元素。

    和往常一样,你的里程可能会有所不同,但我在WebMatrix Beta 2中基于这段代码运行了这个示例,没有任何问题。

    丽莎·Z·摩根 http://www.lairhaven.com