Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 寻求关于如何将JS代码与视图解耦的建议_C#_Javascript_Asp.net Mvc_Decoupling - Fatal编程技术网

C# 寻求关于如何将JS代码与视图解耦的建议

C# 寻求关于如何将JS代码与视图解耦的建议,c#,javascript,asp.net-mvc,decoupling,C#,Javascript,Asp.net Mvc,Decoupling,JavaScript在大多数web解决方案中扮演着越来越重要的角色,但我发现,与服务器端代码相比,将JS代码与视图细节分离要困难得多 为了减少维护负担并使其尽可能适应较小的视图更改,人们正在使用哪些技术来解耦JS代码 为了提供一个具体的例子,我有一个类似以下的视图: <div id="signin" class="auth"> <h2>Sign in</h2> <div id="resultbox" class="box" style="

JavaScript在大多数web解决方案中扮演着越来越重要的角色,但我发现,与服务器端代码相比,将JS代码与视图细节分离要困难得多

为了减少维护负担并使其尽可能适应较小的视图更改,人们正在使用哪些技术来解耦JS代码

为了提供一个具体的例子,我有一个类似以下的视图:

<div id="signin" class="auth">
    <h2>Sign in</h2>
    <div id="resultbox" class="box" style="display: none;"></div>

    <div class="form">
        <p>Required fields are marked <span class="yellow">*</span></p>
        <form action="@Url.Action( MVC.Account.Authenticate() )" method="post" id="authform">
            <label for="Identification">Alias or email <span class="yellow">*</span></label></p>
            @Html.TextBoxFor( m => m.Identification, new { size="22", tabindex="1" } )

            <label for="Password">Password <span class="yellow">*</span></label></p>
            @Html.PasswordFor( m => m.Password, new { size="22", tabindex="2" } )

            <a href="#" class="but_styled" id="btn_signin" tabindex="3">Sign in</a>
        </form>
    </div>
</div>
上面代码的问题是它与视图的外观(必须存在的元素ID、结构等)有多紧密的联系,但我对如何改进它没有什么好的想法

在我看来,如果我继续沿着这条路走下去,JS文件最终会变成一堆正确封装的逻辑,再加上各种特定于视图的东西

这是我能希望做的最好的事情,还是有什么技巧可以用来避免这种混乱


我自己关于如何改进这一点的想法是围绕构建某种服务器端生成的“元素选择器”JS类展开的,这样我就可以编写JS,而无需使用相当多的对类和元素ID的字符串引用。但我不确定人们将如何产生这种情况,或者最终维持这种情况是否会更糟

javascript仍然是视图的一部分,因此我认为将javascript与视图交织在一起的设计不会太糟糕

至于如何让生活变得更轻松,我认为您确实需要尽一切可能找到常见的javascript编码情况,并将它们从视图中重构出来,并将其重构到一个公共库中,以便使用和重用。例如,如果您将HiderResultBox重写为如下所示:

function hideElement(var jqElementSelector, var cssClass1, var cssClass2 var cssClass3) {
    var element = $(jqElementSelector);
    element.hide();
    element.removeClass(cssClass1).removeClass(cssClass2).removeClass(cssClass3);
}
然后,您可以将此视图中的调用替换为:

CommonLib.hideElement('#resultbox', 'info_box', 'error_box');

这样,至少您没有那么多javascript需要维护。它还可以使从服务器生成javascript调用点变得更容易,因为您不需要传递逻辑,只需要传递名称或ID,也不必担心在javascript逻辑中丢失任何类型的javascript智能感知功能。

我想用一种更“功能性”的方式代替ID。。。 也就是说,首先想想javascript代码的功能是什么, 然后以视图可以使用的方式编写代码

你看到区别了吗

您的做法是:先查看,然后查看javascript代码。。。我的建议是:首先是javascript,然后是视图元素。通过这种方式,您可以非常确定自己正在编写一个可重用的javascript代码库

不要使用ID,而是使用类。将代码设置为通用库,以便重用。不需要固定结构,例如“.myClass div a”。。。那个div正在破坏可重用性。。。用一些内部类替换它:“.myClass.innerClass a”,这样您就可以将这些类应用到视图中,而不是让视图主宰代码

尽可能减少直接放入视图中的javascript代码。只需使用对自己库的方法调用,使用简单的描述性方法名称。试着把你的javascript放在一起。尝试不使用声明性javascript。。。我看你已经这么做了。这就是路!=)

不要担心可维护性,因为解耦是提高可维护性的一种行之有效的方法。

一些想法:

  • 不要将功能建立在元素“id”值的基础上,除非视图功能确实包含“自然”唯一的元素。尽可能使用类
  • 使用“data-”属性将功能配置信息从HTML传递到JavaScript。(但不要把代码放在你的“数据-”属性中;在我看来,这是一个非常糟糕的想法。很抱歉,每个人都有自己的想法。)
  • 使用事件发布/子系统在功能“捆绑包”之间进行通信,以控制相互依赖关系
  • 使用
    类来描述不同种类的页面,以提高“连接”的效率。这样,功能代码就可以非常快速地判断给定页面是否需要考虑它
编辑-澄清最后一点:假设您有一些与
页面相关的功能,如日期选择器、自动完成输入或其他类似功能。有时有些功能只对某些类型的形式有意义。在这种情况下,使用body类可以很容易地确定功能是否应该在DOM中查找要影响的元素:

if ($('body').is('.password-form')) { 
  // perform specific initializations
}

我目前使用的web应用程序不是太大,但也不是微不足道的。我发现我可以为整个站点保留一个大的JavaScript集合,并在每个页面上完全相同地包含它,而且我没有任何性能问题(目前)(IE7速度很慢,但这不是原因)

您是否可以提供最后两个项目的示例(或链接到相关内容)?我不完全确定如何将这些建议转化为我可以应用的具体内容。第三个要点是关于名为
Publisher/Subscriber
:+1的设计模式,这也是因为您提到了数据属性的使用!记忆犹新第四点,我认为建议您在body元素中这样做:
用于库页面,而
用于主页。。。我说得对吗?@MiguelAngelo我确实理解pub/sub模式,但不确定它将如何转化为JS。我需要某种经纪人吗?是否有好的库来促进这一点,或者这是一个手工操作的东西?这是有道理的,但似乎只解决了问题的一小部分。我仍然会有一个相当紧密的耦合,尽管正如你所说,这可能是视图的一部分,我应该学会适应它;)如果按宗教信仰使用,您视图的javascript将几乎没有l
CommonLib.hideElement('#resultbox', 'info_box', 'error_box');
if ($('body').is('.password-form')) { 
  // perform specific initializations
}