论坛首页 AJAX版 EXT

Faceye中对JavaScript动态加载

浏览 334 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2008-07-08
在Faceye中,使用到了大量的portlet,每一个portlet都是一个完整的小单元,数量众多的portlet的加载,成了一个思考的问题.

在最开始的时候,考虑过把javascripts写到数据库里面,然后在使用的时候,从数据库中加载进来,后来经过与大量网友的讨论,采用了使用文件方式进行加载.
首先来看Faceye的数据结构.

user--1:1-->PortalContainer--1:n-->Portal--1:n-->PortalColumn--1:n-->portlet

就是说,portlet位于最末端,数量最多.
先来看一下整体是怎么加载的:

/**
 * 创建portlet
 */
com.faceye.portal.BuildPortlet = {
	init : function(portalColumnId) {
		var portalColumn = Ext.getCmp(portalColumnId);
		var portletStore = new Ext.data.JsonStore({
			url : BP + 'portletAction.do?method=getPortletsByPortalColumn',
			root : 'root',
			fields : ['id', 'name', 'source', 'createTime', 'url', 'imageSrc',
					'init']
		});
		portletStore.load({
			params : {
				portalColumnId : portalColumnId
			},
			callback : function(r, options, success) {
				for (var i = 0; i < r.length; i++) {
					var id = r[i].data['id'];
					var name = r[i].data['name'];
					var url = r[i].data['url'];
					Ext.Ajax.request({
						url : r[i].data['url'],
						params : {
							id : id,
							name : name
						},
						success : function(response, options) {
							var source = response.responseText;
							var headerDom = document
									.getElementsByTagName('head').item(0);
							var jsDom = document.createElement('script');
							jsDom.type = 'text/javascript';
							jsDom.language = 'javascript';
							jsDom.defer = true;
							jsDom.text = source;
							headerDom.appendChild(jsDom);
							var portlet = com.faceye.portal.portlet.SinglePortlet
									.init(options.params.id,
											options.params.name);
							portalColumn.add(portlet);
							portalColumn.doLayout();
						}
					});
				}

			}
		});
	}
}



在这一段代码中,最重要的是callback部分.在这里,我们一个portal里面包含数量不等的portalColumn,而一个portalColumn中,又包含数量不等的portlet,所以在这里,我们使用portalColumnId作为加载一个portalColumn中所有portlet的参数,如下:
init : function(portalColumnId)


当一个portlet读取之后,我们会调用一个callback方法作加载动作,如下:
success : function(response, options) {
							var source = response.responseText;
							var headerDom = document
									.getElementsByTagName('head').item(0);
							var jsDom = document.createElement('script');
							jsDom.type = 'text/javascript';
							jsDom.language = 'javascript';
							jsDom.defer = true;
							jsDom.text = source;
							headerDom.appendChild(jsDom);
							var portlet = com.faceye.portal.portlet.SinglePortlet
									.init(options.params.id,
											options.params.name);
							portalColumn.add(portlet);
							portalColumn.doLayout();
						}


这一段代码,主要是创建一个网页中的<script>标签,同时,将我们指定的portlet文件加载进来.
一旦portlet加载进来,我们就会调用另外一个方法:
var portlet = com.faceye.portal.portlet.SinglePortlet
									.init(options.params.id,
											options.params.name);


对portlet进行加载.
在这里,我们所有的portlet的定义,都是以
com.faceye.portal.portlet.SinglePortlet.init(id,name)

方式定义的,这就为我们数量众多的portlet规定了统一的接口,每个portlet只需要进行具体的实现即可,不需要反复的去书写加载代码了.

一个示例的portlet定义如下:

/**
 * www.faceye.com网络支持系统 作者:宋海鹏
 * 我的博客文章,取得并显示当前用户的博客文章。
 * ecsun@sohu.com/myecsun@hotmail.com/QQ:82676683/技术交流群:56927478 说明:Blog porlet
 */
com.faceye.portal.portlet.SinglePortlet = {
	init : function(id, name) {
		var portlet = new Ext.ux.Portlet({
			id : id + '_' + Ext.id(),
			title : name,
			tools : com.faceye.portal.PortletTools
		});
		var store = new Ext.data.Store({
			// baseParams : {
			// categoryId : categoryId
			// },
			proxy : new Ext.data.HttpProxy({
				url : BP + 'articleAction.do?method=getArticles'
			}),
			reader : new Ext.data.JsonReader({
				root : 'root',
				totalProperty : 'total',
				id : 'id',
				fields : ['id', 'name', 'content', 'createTime',
						'categoryName', 'categoryId','discusCount','clickCount']
			})
		});
		store.load({
			params : {
				start : 0,
				limit : 15
			}
		});
		function renderTopic(value, metadata, record, rowIndex, colIndex, store) {
			var html = '<p><a href="#" onclick="com.faceye.portal.portlet.ArticleEditForm.detail(\'{0}\')"><span id="user-blog-article-detail-title">{1}</span></a></p>' +
					'<hr id="user-blog-article-hr"/>'
					+ '<div id="user-blog-article-list-small-tool"><a href="#" onclick="com.faceye.portal.portlet.ArticleEditForm.detail(\'{0}\')">评论({5})</a> ' +
							'| <a href="#" onclick="com.faceye.portal.portlet.ArticleEditForm.detail(\'{0}\')">阅读({6})</a> ' +
							'| 固定链接' +
							'| 类别(<a href="#" onclick="com.faceye.portal.portlet.BlogUtil.reloadGridByCategory(\'{4}\')">{2}</a>) ' +
							'|发表于{3}</div>';
			return String.format(html, record.data.id, record.data.name,
					record.data.categoryName, record.data.createTime,record.data.categoryId,record.data.discusCount,record.data.clickCount);
		}

		var cm = new Ext.grid.ColumnModel([
		// new Ext.grid.CheckboxSelectionModel(),
				{
					id : 'id', // id assigned so we can apply custom css (e.g.
					dataIndex : 'id',
					hidden : true
				}, {
					// header : "标题",
					dataIndex : 'name',
					renderer : renderTopic
				}]);
		// cm.defaultSortable = true;
		var grid = new Ext.grid.GridPanel({
			// el:'topic-grid',
			// renderTo:outGridPanel,
			// title : '我的博客',
			id:'user-blog-grid',
			header : false,
			region : 'center',
			border : false,
			autoHeight : true,
			loadMask : true,
			stripeRows : true,
			trackMouseOver : true,
			layoutConfig : {
				autoWidth : true,
				layout : 'fit'
			},
			// autoExpandMax:1000,
			// width:900,
			store : store,
			cm : cm,
			bodyStyle : 'width:100%;height:100%;',
			trackMouseOver : false,
			// selectRow:Ext.emptyFn,控制选中的记录是否高亮度显示
			sm : new Ext.grid.RowSelectionModel({
				selectRow : Ext.emptyFn
			}),
			// sm : new Ext.grid.CheckboxSelectionModel(),
			loadMask : true,
			viewConfig : {
				forceFit : true,
				enableRowBody : true,
				showPreview : true,
				getRowClass : function(record, rowIndex, p, store) {
					var xf = Ext.util.Format;
					if (this.showPreview) {
						p.body = '<div id="user-blog-article-content-summary">'
								+ xf.ellipsis(
										xf.stripTags(record.data.content), 500)
								+ '</div>';
						p.body += '<hr  id="user-blog-article-hr"/><div id="user-blog-article-list-small-tool"><p>评论()|阅读()|固定链接|类别('
								+ record.data.categoryName + ')|发表于'
								+ record.data.createTime + '</p></div>';
						return 'x-grid3-row-expanded';
					}
					p.body += '<hr id="user-blog-article-hr"/><div id="user-blog-article-list-small-tool"><p>评论()|阅读()|固定链接|类别('
							+ record.data.categoryName + ')|发表于'
							+ record.data.createTime + '</p></div>';
					return 'x-grid3-row-collapsed';
				}
			},
			tbar : [{
				id : 'title-only',
				text : '只看标题',
				iconCls : 'detailChange',
				tooltip : '改变标题的显示方式~',
				handler : function(btn) {
					toggleDetails(btn);
				}
			}],
			bbar : com.faceye.ui.util.PaggingToolBar(15, store)
		});
		// 如果用户已登陆,为用户添加新增文章的权限.
		com.faceye.ui.UserLogin.is().load({
			callback : function(r, options, success) {
				if (r[0].data.login === 'yes') {
					var topToolBar = grid.getTopToolbar();
					topToolBar.add('-',{
						id : 'add',
						text : '撰写新日志',
						tooltip : '添加新日志~~',
						iconCls : 'add',
						handler : function(btn) {
							com.faceye.portal.portlet.ArticleEditForm.to();
						}
					});
//					topToolBar.doLayout();
				}
			}
		});
		// grid.setHeight(500);
		function toggleDetails(btn) {
			var view = grid.getView();
			if (view.showPreview) {
				btn.setText('显示摘要');
				view.showPreview = false;
			} else {
				view.showPreview = true;
				btn.setText('只看标题');
			}
			view.refresh();
		}
		portlet.add(grid);
		return portlet;
	}
};
com.faceye.portal.portlet.BlogUtil={
	reloadGridByCategory:function(id){
		var grid=Ext.getCmp('user-blog-grid');
		grid.store.load({
			params : {
				start : 0,
				limit : 15,
				categoryId:id
			}
		});
	}
};


******************************************************************
关于FaceYe开源portal的其它更多内容包括:

FaceYe用户及开发人员提供文档(以下内容为FaceYe开发人员或用户提供,请尊重原著):

******************************************************************
   
论坛首页 AJAX版 EXT

跳转论坛:
JavaEye推荐