【问题标题】:javascript code architecture questionjavascript代码架构问题
【发布时间】:2013-01-02 01:13:56
【问题描述】:

我将要制作一个客户端相当繁重的网络应用程序。我不确定如何组织我的 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代码架构的方式是什么?谢谢。

[update] :正如您从上面看到的那样,这个网络应用程序仅以 ajax 方式处理产品 CRUD、类别 CRUD。我在这里只展示一个 sn-p,所以你们知道我想要实现什么以及我的问题是什么。再次,我要求为我组织此应用程序代码的方法提供输入。

【问题讨论】:

  • 呃,你真的在​​做另一个 JS 库吗?在投入时间、痛苦和在 N 个平台上正确完成这项工作的学习曲线之前,所有这些都以不同的方式略有损坏,看看 jQuery、YUI 等等等。我个人最喜欢的是 jQuery,但几乎任何东西都比从头开始构建一个新的。
  • @Peter:不。看看我的代码,我不是想构建一个 JS 库。我正在尝试开发具有繁重客户端的 Web 应用程序。我正在寻求建筑方面的建议。
  • 他在询问代码组织。没有它,世界上所有的 jQuery 看起来都像垃圾。

标签: javascript


【解决方案1】:

这类似于我做 JavaScript 项目的方式。以下是我使用的一些技巧:

  • 为每个单例对象创建一个文件。在您的代码中,将 ajax、中间层和 ui 接口存储在单独的文件中
  • 为项目中通常的3层创建一个全局单例对象; GUI、后端和应用程序
  • 切勿在后端对象之外的任何地方使用纯 ajax。将服务器端页面的 URL 存储在 Backend 对象中,并创建一个使用该 URL 联系服务器的函数。
  • 在服务器上有一个可以向客户端报告错误和异常的 JSON 类。在 Backend 对象中,检查返回的 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 对象存储在 Backend 对象中的某个位置来改进,但这不是必需的。

【讨论】:

  • @Marius:您能否更具体地了解“将 URL 存储到后端对象中的服务器端页面并创建一个使用该 URL 联系服务器的函数。”。谢谢。其他观点我完全同意。
  • @Marius:现在明白了。我在以前的项目中采用了类似的方法。我认为这里的规则是只使用一层进行客户端-服务器数据流。
  • @Shawn:我猜 Marius 的想法是有一个中心位置来处理沟通。
【解决方案2】:

当您构建不平凡的东西时,封装对于使事物长期可维护很重要。例如,JS UI 不仅仅是简单的 JS 方法。一个 UI 组件由 css、模板、逻辑、本地化、资产(图像等)组成。

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

【讨论】:

    【解决方案3】:

    对于客户端 ajax 处理,我有一个包含我所有 url 的 URL 对象,并且我有一个处理 ajax 的 ajax 对象。这不是一种以中心为中心的方法。就我而言,我有不同的 url 处理不同的任务。我还将一个回调函数传递给 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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-24
      • 2012-10-25
      • 1970-01-01
      • 2010-09-07
      • 2013-02-22
      • 1970-01-01
      相关资源
      最近更新 更多