2009-12-13 101 views
1

我即将制作一个网络应用程序,它将有一个非常沉重的客户端。我不知道要组织我的javascript代码的方式,但这里是一个基本的想法:javascript代码体系结构问题

// the namespace for the application 
var app = {}; 

// ajax middle layer 
app.products = { 
    add : function(){ 
    // send ajax request 
    // if response is successful 
     // do some ui manipulation 
     app.ui.products.add(json.data); 
    }, 
    remove : function(){}, 
    ... 
}; 
app.categories = { 
    add : function(){}, 
    .... 
}; 

// the ui interface which will be called based on ajax responses 
app.ui = {}; 
app.ui.products = { 
    add : function(product_obj){ 
    $('#products').append("<div id='"+product_obj.id+"'>"+product_obj.title+"</div>"); 
    } 
}; 
app.ui.categories = {}; 

任何人有类似的经验告诉我,这种做法的利弊?您设计客户端JavaScript代码架构的方式是什么?谢谢。

[更新]:正如你从上面看到的,这个网络应用程序处理产品CRUD,仅以ajax方式分类CRUD。我只是在这里展示一个片段,所以你们知道我想要达到什么以及我的问题是什么。再次,我要求输入我的方法来组织这个应用程序的代码。

+1

呃,你真的在​​做另一个JS库吗?在投入时间之前,痛苦以及在N个平台上获得这种权利的学习曲线,所有这些都以不同的方式轻微破坏,看看jQuery,YUI等等。我个人最喜欢的是jQuery,但几乎所有东西都比从头开始建立一个新的。 – 2009-12-13 06:15:04

+1

@彼得:没有。看看我的代码,我没有试图建立一个JS库。我试图开发一个沉重的客户端的Web应用程序。我正在寻求建筑建议。 – Shawn 2009-12-13 06:19:06

+2

hes询问代码组织。没有这些,世界上所有的jQuery看起来都是垃圾。 – seanmonstar 2009-12-13 06:40:18

回答

3

这和我做JavaScript项目的方式很相似。这里有一些我已经使用的技巧:

  • 为每个单例对象创建一个文件。在您的代码中,将ajax,中间层和ui界面存储在单独的文件中
  • 通常在项目中为3个层创建一个全局单例对象; GUI,后端和应用程序
  • 切勿从后端对象外的任何地方使用纯粹的ajax。将URL存储到Backend对象中的serverside页面,并创建一个使用该URL的函数来联系服务器。
  • 在服务器上有一个可以向客户端报告错误和异常的JSON类。在后端对象中,检查返回的JSON对象是否包含错误,并在GUI类中调用serverError函数以向用户(或开发人员)呈现错误。

这里是一个后端对象的示例:

var Backend = {}; 
Backend.url = "/ajax/myApp.php"; 
Backend.postJSON = function(data, callback){ 
    var json = JSON.stringify(data); 
    $.ajax({ 
    type: "POST", 
    url: Backend.url, 
    data: "json="+json, 
    dataType: "json", 
    success: function(response){ 
     if(response){ 
     if(response.task){ 
      return callback(response); 
     }else if(response.error){ 
      return Backend.error(response); 
     } 
     } 
     return Backend.error(response); 
    }, 
    error: function(response){ 
     Backend.error({error:"network error", message:response.responseText}); 
    }, 
    }); 
}; 
Backend.error = function(error){ 
    if(error.message){ 
    Client.showError(error.message, error.file, error.line, error.trace); 
    } 
}; 

这可以通过存储在后端对象Ajax对象somewher得到改善,但它不是必需的。

+0

@Marius:您能否更具体地说:“将URL存储到Backend对象中的serverside页面,并创建一个使用该URL来联系服务器的函数。”谢谢。其他观点我完全同意。 – Shawn 2009-12-13 06:24:07

+0

@Marius:现在明白了。我在以前的项目中采取了类似的方法。我认为这里的规则是仅使用一层用于客户端 - 服务器数据流。 – Shawn 2009-12-13 06:41:14

+0

@Shawn:我想Marius的想法是有一个中心位置来处理沟通。 – Codism 2009-12-13 06:43:54

0

当你构建一些不重要的东西时,封装对于长期维护是非常重要的。例如,JS UI不仅仅是简单的JS方法。 UI组件由css,模板,逻辑,本地化,资产(图片等)组成。

产品模块也是一样的,它可能需要自己的设置,事件总线,路由。在集成您选择的一组库中执行一些基本的体系结构代码非常重要。当我开始大规模的JS开发时,这对我来说是一个挑战。我将一些最佳实践汇编到http://boilerplatejs.org的参考架构中,供有人使用我获得的经验。

0

对于客户端ajax处理我有一个URL对象,它包含我所有的url,并且我有一个处理ajax的ajax对象。这不是一个中心的方法。在我的情况下,我有不同的网址处理不同的任务。我还将一个回调函数传递给ajax对象。

var controller_wrapper = { 
    controller: { 
    domain: "MYDOMAIN.com", 
    assets: "/assets", 
    prefix: "", 
    api: { 
     domainer: "http://domai.nr/api/json/info", 
     tk_check: "https://api.domainshare.tk/availability_check" 
    }, 
    "perpage": "/listings/ajax", 
    "save_image": "/members/saveImage", 
    "update": "/members/update", 
    "check_domain": "/registrar/domaincheck", 
    "add_domain": "/registrar/domainadd", 
    "delete_listing": "/members/deactivateProfile", 
    "save_listing": "/members/saveProfile", 
    "get_images": "/images/get", 
    "delete_image": "/images/delete", 
    "load_listing": "/members/getProfile", 
    "load_listings": "/members/getListings", 
    "loggedin": "/members/loggedin", 
    "login": "/members/login", 
    "add_listing": "/members/add", 
    "remove": "/members/remove", 
    "get": "/members/get", 
    "add_comment": "/members/addComment", 
    "load_status": "/api/loadStatus" 
} 
} 

    var common = { 
    pager: 1, 
    page: 0, 
    data: { 
    saved: {}, 
    save: function (k, v) { 
     this.saved[k] = v; 
    } 
}, 
ajax: { 
    callback: '', 
    type: 'POST', 
    url: '', 
    dataType: '', 
    data: {}, 
    add: function (k, val) { 
     this.data[k] = val; 
    }, 
    clear: function() { 
     this.data = {}; 
    }, 
    send: function() { 
     var ret; 
     $.ajax({ 
      type: this.type, 
      url: this.url, 
      data: this.data, 
      dataType: this.dataType !== '' ? this.dataType : "json", 
      success: function (msg) { 
       if (common.ajax.callback !== '') { 
        ret = msg; 
        common.ajax.callback(ret); 
       } else { 
        ret = msg; 
        return ret; 
       } 
       return; 
      }, 
      error: function (response) { 
       console.log(response); 
       alert("Error"); 
      } 
     }) 
    } 
} 
    var callback = function (results) { 
    console.log(results 
    } 
    common.ajax.callback = callback; 
    common.ajax.type = "jsonp"; 
    common.ajax.type = "POST"; 
    common.ajax.url = controller_wrapper.controller.perpage; 
    common.ajax.add("offset", common.page); 
    common.ajax.add("type", $("select[name='query[type]']").val()); 
    common.ajax.add("max", $("select[name='query[max]']").val()); 
    common.ajax.add("min", $("select[name='query[min]']").val()); 
    common.ajax.add("bedrooms", $("select[name='query[bedrooms]']").val()); 
    common.ajax.add("sort", $("select[name='query[sort]']").val()); 
    common.ajax.send();