用RequireJS编写JavaScript模块

模块化编写JavaScript,在web前端程序不断扩大的时候,是一个很好的重构技术。

下面的例子有两个模块,

artDialog模块依赖jquery和jquery.artDialog库,提供了弹出错误对话框的功能。

require.config({
	paths: {
		"jquery": "../thirdParty/jquery-1.8.0.min",
		"jquery.artDialog": "../../plugin/artDialog4.1.6/jquery.artDialog"
	}
});

define("artDialog",
       ["jquery", "jquery.artDialog"],
       function ($, artDialog) {
	       return {
		       cancelText: "",

		       language: "",

		       // language should be either 'cn' or 'en'
		       init: function (language) {
			       this.language = language;
			       if (language === "cn") {
				       this.cancelText = "取消";
			       } else {
				       this.cancelText = "Cancel";
			       }
		       },

		       error: function (message) {
			       $.dialog({
				       icon: "error",
				       content: message,
				       cancelVal: this.cancelText,
				       ok: function () {
					       this.close();
				       }
			       });
		       }
	       };
       }
      );

解释一下:

1.require.config里面的paths 用了key: value形式,key是名称简写,path是从当前位置找到依赖文件的路径

2.define是定义模块的意思,第一个参数"artDialog"是指这个模块的名称,数组里面是本模块依赖的其他js模块,

3.RequireJS看到2定义的依赖模块后,会去加载这些js文件,加载完成后,会调用函数function($, artDialog)

4.回调函数反回一个json对象,里面有成员变量和函数。


ajaxUtility模块内部使用了artDialog模块,看看代码:

require.config({
	paths: {
		"jquery": "../thirdParty/jquery-1.8.0.min",
		"artDialog": "./dialog"
	}
});

define("ajaxUtility",
       ["jquery","artDialog"],
       function ($, artDialog) {
	       return {
		       cancelText: "",

		       language: "",

		       // language should be either 'cn' or 'en'
		       init: function (language) {
			       this.language = language;
			       artDialog.init(language);
			       if (this.language === "cn") {
				       this.cancelText = "取消";
			       } else {
				       this.cancelText = "Cancel";
			       }
		       },

		       // popup an error dialog
		       defualtErrorHandler: function (jqXHR, textStatus) {
			       artDialog.error("Ajax request got an error:" + textStatus);
		       },

		       // execute .ajax function and except the returned data type is json
		       // handler(msg) will be callback when .ajax succeeded
		       // errorHandler(jqXHR, textStatus) willl be callback if .ajax failed
		       exe: function (urlPath, asyncWay, method, dataValue, handler, errorHandler, context) {
			       var error, request;
			       if (errorHandler) {
				       error = errorHandler;				       
			       } else {
				       error = this.defaultErrorHandler;
			       }
			       request = $.ajax({
				       url: urlPath,
				       async: asyncWay,
				       type: method,
				       dataType: 'json',
				       data: dataValue
			       });

			       // request.done(handler);

			       request.done(
				       (function (ob, hdl) {
					       return function(msg) {
						       hdl(ob, msg);  
					       }
				       })(context, handler)
			       );
			       request.fail(error);
		       },

		       // post data to server using .ajax
		       // handler(msg) will be callback when .ajax succeeded
		       // errorHandler(jqXHR, textStatus) willl be callback if .ajax failed
		       post: function (urlPath, asyncWay, dataValue, handler, errorHandler, context) {
			       this.exe(urlPath, asyncWay, 'POST', dataValue, handler, errorHandler, context);
		       },

		       // call web method with GET to server using .ajax
		       // handler(msg) will be callback when .ajax succeeded
		       // errorHandler(jqXHR, textStatus) willl be callback if .ajax failed
		       get: function (urlPath, asyncWay, dataValue, handler, errorHandler, context) {
			       this.exe(urlPath, asyncWay, 'GET', dataValue, handler, errorHandler, context);
		       }
	       };
       }
      );


1.require.config里面说明了模块artDialog在dialog.js文件中

2.define语句定义了ajaxUtility模块,并且在加载dialog.js文件和jquery完成后,调用函数function($, artDialog) ,注意,此时参数artDialog就是前面一个模块返回出来的对象。


依赖加载的说明,chrome调试发现,不用担心共同依赖的jquery会被加载两次,RequireJS很智能。也不用担心依赖顺序,只要每个模块都正确定义了自己的依赖模块,顺序就会有保障。


最后给一个第三个模块演示如何依赖这两个模块,以及其他模块:

require.config({
	paths: {
		"ajaxUtility": "./ajax_utility",
		"jquery.validate": "../../plugin/jquery-validation-1.9.0/jquery.validate.min",
		"flexigrid": "../../plugin/flexigrid-1.1/js/flexigrid",
		"flexigrid.pack": "../../plugin/flexigrid-1.1/js/flexigrid.pack",
		"jquery.ui": "../../plugin/jquery-ui-1.8.23.custom/js/jquery-ui-1.8.23.custom.min"
	}
});

require(["ajaxUtility"], function(ajaxUtility) {
	ajaxUtility.init("cn");
	require(["jquery.validate", "flexigrid", "flexigrid.pack", "language", "jquery.ui"], function(util) {
		require(["log"], function(util) {
			$(document).ready(function() {
				log.init();
			})
		});
	});
});
最外层的require加载的是ajaxUtility,因此它最先被加载,juery, jquery.artDialog和dialog.js都会被加载,然后其他依赖比如jquery.ui就无须担心jquery是否加载。




你可能感兴趣的:(用RequireJS编写JavaScript模块)