JavaScript不需要编译即可运行,这让JavaScript构建的应用程序可以变得很灵活。我们可以根据需要动态从服务器加载JavaScript脚本来创建和控制UI来与用户交互。下面结合Ext JS来说明如何从服务器上动态加载JS脚本来动态创建窗体。
项目结构如下:其中GetJSUI一般处理程序用来从数据库表中抓取UI配置,并返回到客户端;Contents文件夹下用HTML文件和JS库等。
可以用下面的SQL在MSSQL中创建表,其中JavaScriptContent字段存储具体的JS脚本。
CREATE TABLE [dbo].[Ext_Dynamic_Form](
[ID] [nvarchar](50) NOT NULL,
[UniName] [nvarchar](50) NULL,
[JavaScriptContent] [nvarchar](4000) NULL,
[Memo] [nvarchar](200) NULL,
CONSTRAINT [PK_Ext_Dynamic_Form] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
) ON [PRIMARY]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CMCloudDBHelper;
namespace extjs6.Services
{
///
/// author:jackwangcumt
///
public class GetJSUI : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string js = "";
context.Response.ContentType = "text/plain";
//context.Response.ContentType = "text/javascript";
CMCDataAccess da = new CMCDataAccess();
string SQLForJS = "select * FROM Ext_Dynamic_Form where ID='006'";
System.Data.DataTable dt= da.GetDataTable(SQLForJS);
if(dt!=null)
{
if(dt.Rows.Count==1)
{
js = dt.Rows[0]["JavaScriptContent"].ToString();
}
}
//utf-8
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
context.Response.Write(js);
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
Dynamically generate forms from server javascript//load *.js file from server
function loadScript(url, callback) {
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState) { //IE
script.onreadystatechange = function() {
if (script.readyState == "loaded" ||
script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function() {
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
//load js text from server
function loadScriptSrc(js, callback) {
var script = document.createElement("script")
script.type = "text/javascript";
//script.async = true;
if (script.readyState) { //IE
script.onreadystatechange = function() {
if (script.readyState == "loaded" ||
script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function() {
callback();
};
}
script.text = js;
console.log(script);
document.getElementsByTagName("head")[0].appendChild(script);
//不能少
callback();
}
//Ext JS 6
Ext.onReady(function() {
//https://www.sencha.com/forum/showthread.php?268193-How-to-load-content-dynamically-for-tabpanel
var pmain = Ext.widget('panel', {
renderTo: document.body,
height: 800,
width: 800,
layout: 'border',
items: [{
title: 'West',
region: 'west',
width: 200,
collapsible: true
}, {
xtype: 'tabpanel',
region: 'center',
items: [{
title: 'First Tab',
itemId: 'tab01',
}, {
title: 'Second Tab',
layout: 'fit',
loader: {
url: 'Form.json',
autoLoad: true,
renderer: 'component'
}
}]
}]
});
//ajax config
var reqConfig = {
url: '../Services/GetJSUI.ashx',
method: 'get',
callback: function (options, success, response) {
// var msg = ['success:', success, '\n', 'data:', response.responseText];
// alert(msg.join(''));
loadScriptSrc(response.responseText, function() {
Ext.Msg.alert("loaded js","从服务器加载JS完成");
var gp = Ext.create("gpView");
Ext.ComponentQuery.query('#tab01')[0].add(gp);
});
}
};
Ext.Ajax.request(reqConfig);
//loadScript("dynamicLoadJS2.js", function() {
// Ext.Msg.alert("loaded");
// var gp = Ext.create("gpView");
// //console.log(gp);
// //gp.body.renderTo(pmain);
// // Ext.ComponentQuery.query('#tab01')[0].add({
// // html: 'Oh, Hello.'
// // });
// Ext.ComponentQuery.query('#tab01')[0].add(gp);
//});
});
这样我们可以做一个主框架,然后构建菜单和权限等通用体系,通过在数据库中配置菜单及UI,可以动态扩展应用。