您将如何组织大型复杂的Web应用程序(请参阅基本示例)?

Anu*_*rag 17 javascript design-patterns web-applications code-organization

为了让事情变得有趣并且关闭我最后的开放式问题,以一种合理的架构以良好的组织方式实现以下功能的解决方案获得了很好的赏金.完整的代码是在jsfiddle,随时问任何问题:)

您通常如何组织客户端极其丰富的复杂Web应用程序.我已经创建了一个人为的例子来表明如果对于大型应用程序来说管理不好的话,它很容易陷入混乱状态.随意修改/扩展此示例 - http://jsfiddle.net/NHyLC/1/

该示例基本上反映了SO上的评论发布部分,并遵循以下规则:

  1. 在将多个空格修剪为一个空格后,必须至少包含15个字符.
  2. 如果Add Comment单击,但在删除多个空格后大小小于15,则显示带有错误的弹出窗口.
  3. 指示剩余字符数量并使用颜色编码进行汇总.灰色表示小评论,棕色表示中等评论,橙色表示大评论,红色表示评论溢出.
  4. 一条评论只能每15秒提交一次.如果过早提交评论,请显示带有相应错误消息的弹出窗口.

我在这个例子中注意到了几个问题.

  • 理想情况下,这应该是一个小部件或某种打包的功能.
  • 每15秒评论一次,最少15个字符的评论属于某些应用程序范围的策略,而不是嵌入到每个小部件中.
  • 太多的硬编码值.
  • 没有代码组织.模型,视图,控制器都捆绑在一起.并非MVC是组织富客户端Web应用程序的唯一方法,但在此示例中没有.

你会如何清理它?沿途应用一点MVC/MVP?

这里有一些相关的函数,但如果你在jsfiddle上看到整个代码会更有意义:

/**
 * Handle comment change.
 * Update character count. 
 * Indicate progress
 */
function handleCommentUpdate(comment) {
    var status = $('.comment-status');

    status.text(getStatusText(comment));
    status.removeClass('mild spicy hot sizzling');
    status.addClass(getStatusClass(comment));
}

/**
 * Is the comment valid for submission
 * But first, check if it's all good.
 */
function commentSubmittable(comment) {
    var notTooSoon = !isTooSoon();
    var notEmpty = !isEmpty(comment);
    var hasEnoughCharacters = !isTooShort(comment);

    return notTooSoon && notEmpty && hasEnoughCharacters;
}

/**
 * Submit comment.
 * But first, check if it's all good!
 */
$('.add-comment').click(function() {
    var comment = $('.comment-box').val();

    // submit comment, fake ajax call
    if(commentSubmittable(comment)) {
        .. 
    }

    // show a popup if comment is mostly spaces
    if(isTooShort(comment)) {
        if(comment.length < 15) {
            // blink status message
        }
        else {
           popup("Comment must be at least 15 characters in length.");
        }
    }
    // show a popup is comment submitted too soon
    else if(isTooSoon()) {
        popup("Only 1 comment allowed per 15 seconds.");
    }

});
Run Code Online (Sandbox Code Playgroud)

编辑1:

@matpol感谢您对包装器对象和插件的建议.这将是对现有混乱的重大改进.但是,插件并不是独立的,正如我所提到的,它将成为更大的复杂应用程序的一部分.客户端/服务器端的应用程序范围的策略将决定评论的最小/最大长度,用户评论的频率等等.当然,插件可以作为参数提供此信息.

此外,对于富客户端应用程序,数据必须与其html表示分离,因为可以保存许多服务器往返,因为应用程序是数据感知的,并且可以在本地存储事物,并在服务器上定期更新,或应用程序本身内的有趣事件(例如窗口关闭时).这就是我不喜欢插件方法的原因.它可以像提供打包的表示一样工作,但它仍然以DOM为中心,当你在应用程序中有20个这样的插件时,这将是有问题的,这绝不是一个荒谬的数字.

Xia*_*ian 23

我这样做的方式是3倍.

  1. 在命名空间内的小型明确定义的类中封装javascript
  2. Javascript类应该有HTML,它们需要"注入"它们作为依赖,允许浏览器外单元测试
  3. 尽可能多地将客户端功能移动到服务器,并使用称为AHAH的概念

Javascript名称间距

这可以轻松实现,并已在其他帖子中介绍过,例如,这是否有一种"简洁"的方法来在JavaScript中执行命名空间?

小封装类

Javascript代码,就像服务器端代码一样,应该用小的内聚类和方法很好地封装.每个类都位于一个单独的文件中,与其所在的命名空间一起命名,例如:MyCompany.SomePackage.MyClass.js.通过在构建时组合和缩小这些类文件,可以节省对每个文件的过多HTTP请求.

Javascript中的依赖倒置

因此,有效而不是选择您在课堂内工作所需的元素,如下所示:

var MyNamespace.MyClass = function() {
  var elementINeed = $('#IdOfElementINeed');
}
Run Code Online (Sandbox Code Playgroud)

你会这样注入它:

var foo = new MyNamspace.MyClass($('#IdOfElementINeed'));

var MyNamespace.MyClass = function(incomingDependency) {
  var elementINeed = incomingDependency;
}
Run Code Online (Sandbox Code Playgroud)

这种技术非常适合可测试的javscript,并通过代码的MVC样式分层来关注问题.

AHAH和客户端简化

AHAH是一种相当古老的技术,在网络开发中已经存在了相当长的一段时间,尽管由于其纯粹的简单性而在网络爱好者中重新崛起.但是,哲学必须超过建筑技术水平,并且必须用作所有客户端javascript的替代品,例如:验证,显示/隐藏动态内容,计算等

以前您可能已经附加了具有客户端复杂性的onClick事件:

$('#someElement').click(function(){
  // insert complex client-side functionality here, such as validating input
  // eg var isValid = $(this).val() < minimumCommentLength;
  // update page based on result of javascript code
  // eg $('#commentTooLong').show();
})
Run Code Online (Sandbox Code Playgroud)

现在,您只需将ajax请求触发回服务器即可获取新的HTML,并简单地替换您感兴趣的全部或部分元素:

$('#addCommentButton').click(function(){
  $.ajax({ 
    url: "/comment/add", 
    context: document.body, success: 
    function(responseHTML){
        $('body').html(reponseHTML);
      }});
})
Run Code Online (Sandbox Code Playgroud)

显然这是一个简单的例子,但是当有效使用时,页面上的任何javascript事件,只需触发相同的ajax请求和HTML替换,大大减少了所需的客户端代码量.将其移动到可以进行有效测试的服务器上.

AHAH谔谔,会认为这是不运行一个网站一个高性能的方式,不过我已经使用并看到有56K调制解调器接入,并大规模扩展的公共网络的网站的网站这种技术.结果当然是慢,但你仍然可以产生子100毫秒的往返行程,这几乎是瞬间的人类.