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>
JS部分分为两个文件 - 第一个是我的“业务逻辑”类,第二个主要用于连接:
(function (pp, $, undefined) {
pp.account = {};
function hideResultBox() {
var box = $('#resultbox');
box.hide();
box.removeClass('info_box').removeClass('error_box');
}
function showResultBox(result) {
var box = $('#resultbox');
if (result.Success === true) {
$('#resultbox_content').html(result.Message);
box.addClass('info_box').show();
} else {
$('#resultbox_content').html(result.Message);
box.addClass('error_box').show();
var messages = '';
for (var error in result.Errors) {
messages += '<li>' + result.Errors[error] + '</li>';
}
if (messages !== '')
$('#resultbox_content').append('<br /><ul>' + messages + '</ul>');
}
}
pp.account.authenticate = function (data) {
hideResultBox();
$.post('/account/authenticate', data, function (result) {
showResultBox(result);
if (result.Success === true) {
setTimeout(function () { window.location = result.Url; }, 1000);
}
});
};
})(window.pressplay = window.pressplay || {}, jQuery);
接线部分:
$(document).ready(function () {
$('#signin a').live('click', function () {
var form = $(this).closest('form').serialize();
pressplay.account.authenticate(form);
return false;
});
});
上面代码的问题在于它与视图的外观(必须存在的元素ID,结构等)有多紧密关系,但我对如何改进它没有好的想法。
在我看来,如果我继续沿着这条路走下去,JS文件最终会成为一堆混乱的正确封装逻辑,并结合各种特定于视图的东西。
这是我希望做的最好的,还是我可以采用任何技术来避免一些混乱?
我自己关于如何改进这个的想法围绕构建某种服务器端生成的“元素选择器”JS类,这样我就可以编写JS而不需要对类和元素id使用尽可能多的字符串引用。但我不确定如何产生这种情况,或者最终是否会更糟糕。
答案 0 :(得分:3)
一些想法:
<body>
类来表征不同类型的页面,以提高“布线”的效率。这样,功能代码可以非常快速地判断是否需要考虑给定页面。 编辑 - 澄清最后一个:假设您有一些与<form>
页面有关的功能,例如日期选择器,或自动完成输入,或其他像这样的东西。有时,某些功能仅对表单的某些种有意义。在这种情况下,使用body类可以很容易地弄清楚一个特性是否应该费心去查看DOM以便影响元素:
if ($('body').is('.password-form')) {
// perform specific initializations
}
我目前参与的网络应用程序并不是太大,但它也不是一件容易的事。我发现我可以为整个站点保留一个大的JavaScript集合并在每个页面上包含相同的内容,而且我没有任何性能问题(目前)(IE7很慢,但这种技术不是那)。
答案 1 :(得分:1)
javascript仍然是您视图的一部分,所以我不相信设计太糟糕,让您的javascript与您的视图交织在一起。
至于可以做些什么来让生活更轻松,我认为你真的需要做任何事情来找到常见的javascript编码情况,并将它们重构出视图,并进入一个可以使用它的公共库并重复使用。例如,如果您将hideResultBox重写为如下所示:
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调用点,因为你没有传递逻辑,只是名字和&amp;或者ids,而不必担心在你的javascript逻辑中丢失任何类型的javascript intellisense能力。
答案 2 :(得分:1)
而不是ID,我会用更多的“功能方式”来思考 ...... 也就是说,首先考虑一下javascript代码的功能是什么, 然后以您的视图可以使用的方式创建代码。
你看到了区别吗?
你的方式是:首先查看,然后查看javascript代码...我的建议是:首先是javascript,然后是视图元素。这样你就可以确定你正在编写一个可重用的javascript代码库。
不使用ID,而是使用类。使代码像是一个通用的lib,你可以重用。不需要固定的结构,例如“.myClass div a”... div正在杀死可重用性......用一些内部类替换它:“。myClass .innerClass a”,这样你就可以将类应用到你的视图中,而不是让视图主宰代码。
尽量减少直接放在视图中的javascript代码。只需对自己的库使用方法调用,使用简单的描述性方法名称。尝试将您的JavaScript放在一起。尽量不要使用声明性的javascript ...因为我看到你已经这样做了。这是要走的路! =)
不要担心可维护性,因为解耦是提高可维护性的有效方法。