ExtJS 4 组件化编程,动态加载,面向对象,Direct结合成功,目前为止我的最佳实践
ExtJS4中支持组件化编程和Direct,官方实例中分别提供了两种技术的示例,但没有两种方式结合的例子,经多次测试,由于4.0中存在的bug(暂时这么认为,也许是我水平烂),两种方式结合会产生一系列问题,在静态加载、动态加载、Direct结合的过程中(尤其是采用Direct的时候,用url不会出错),经常性的报错。
官方论坛也没有相关资料,中文也没找到。
分析2天源代码+调试+测试各种结合方式(new/define/create/各参数调节),终于找到一个稳定运行的实现方式,也很好的体现了面向对象及组件化编程的思想。示例如下,相关解释卸载注释中,注意此示例必须结合ExtJS4运行。
代码如下:
1、html页(关键部分代码)
1 <!--加载ExtJS的CSS和js,也可以只加载核心包,然后按照提示加载需要的js(未测试)-->
2 <!--其他js全部使用动态加载,在head部分不需要引用js-->
3 <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css" />
4 <link rel="stylesheet" type="text/css" href="css/application.css" />
5 <script src="ext/ext-all.js" type="text/javascript"></script>
6 <script src="ext/ext-lang-zh_CN.js" type="text/javascript"></script>
7 <!--本例中使用.Net,此处加载Direct的Api-->
8 <script src="Api.ashx" type="text/javascript"></script>
9 <script type="text/javascript">
10 //以下设置必须在Ext.onReady之前
11 //动态配置打开
12 Ext.Loader.setConfig({enabled: true});
13 //设置组件路径
14 Ext.Loader.setPath('App', 'js');
15 //加载MainViewport组件,注意MainViewport里面需要的js不需要在此加载,在MainViewport的define中用requires参数定义就可以,其他组件类似
16 //每种组件只需要考虑自己的require即可
17 Ext.require([
18 'App.MainViewport'
19 ]);
20 //加入Direct的Provider
21 Ext.direct.Manager.addProvider(Ext.app.USER_API);
22 Ext.onReady(function () {
23 Ext.QuickTips.init();
24 Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));
25 //舍弃new函数,改用Ext.create
26 Ext.create(App.MainViewport);
27 setTimeout(function () {
28 Ext.get('loading').remove();
29 Ext.get('loading-mask').fadeOut({ remove: true });
30 Ext.getCmp('MainLicense').collapse();
31 }, 250);
32 });
33 </script>
2、MainViewport.js(定义App.MainViewport类,由于指定了路径,这个js文件必须放在js目录下,而且文件名称必须是MainViewport.js,否则无法加载)
1 //组件名称、js路径、js文件名必须匹配
2 Ext.define('App.MainViewport',{
3 //加载MainViewport内的各组件
4 requires:['App.MainFunctionPanel','App.Banner','App.Licence'],
5 extend:'Ext.Viewport',
6 layout: 'border',
7 items: [
8 //使用xtype定义items,利用id和Ext.getCmp获取相应的对象,或者通过itemId和getComponent()获取对象,注意scope的不同
9 {xtype: 'Banner',itemId: 'MainBanner',region: 'north',margins: '0 0 0 5'},
10 {xtype: 'Licence',id: 'MainLicense',region: 'south',margins: '0 0 0 0',contentEl: 'south'},
11 {xtype:'MainFunctionPanel',region: 'west'},
12 //也可以使用Ext.create创建对象,但不要使用new
13 Ext.create('Ext.tab.Panel', {
14 region: 'center',
15 id:'mainTabPanel',
16 deferredRender: false,
17 activeTab: 0,
18 items: [{
19 id:'mainFilePanel',
20 title: '文件浏览',
21 autoScroll: true,
22 listeners: {
23 activate: function () { Ext.getCmp('mainFunctionFile').expand() }
24 }
25 },{
26 id:'mainSearchPanel',
27 title: '文件查找',
28 autoScroll: true,
29 listeners: {
30 activate: function () { Ext.getCmp('mainFunctionSearch').expand() }
31 }
32 }]
33 })]
34 });
3、App.MainFunctionPanel类,放置的位置参照以上
1 //MainFunctionPanel类,继承Ext.Panel
2 Ext.define('App.MainFunctionPanel',{
3 extend:'Ext.Panel',
4 requires:'App.MainFunctionTree',
5 alias:'widget.MainFunctionPanel',
6 title: '功能选择',
7 split: true,
8 width: 200,
9 minWidth: 175,
10 maxWidth: 400,
11 collapsible: true,
12 animCollapse: true,
13 margins: '0 0 0 5',
14 layout: 'accordion',
15 items: [
16 {
17 xtype:'FunctionTree',
18 title: '文件浏览',
19 id:'mainFunctionFile',
20 iconCls: 'nav', // see the HEAD section for style used
21 listeners: {
22 //beforerender: function () { alert('beforerender'); },
23 //beforecollapse: function () { alert('beforecollapse'); },
24 //beforeexpand: function () { alert('beforeexpand'); },
25 expand: function () { Ext.getCmp('mainTabPanel').setActiveTab(Ext.getCmp('mainFilePanel')); }
26 }
27 }, {
28 title: '文件查找',
29 id:'mainFunctionSearch',
30 html: '<p>Some settings in here.</p>',
31 iconCls: 'settings',
32 listeners: {
33 //beforerender: function () { alert('beforerender'); },
34 //beforecollapse: function () { alert('beforecollapse'); },
35 //beforeexpand: function () { alert('beforeexpand'); },
36 expand: function () { Ext.getCmp('mainTabPanel').setActiveTab(Ext.getCmp('mainSearchPanel')); }
37 }
38 }, {
39 title: '系统管理',
40 id:'mainFunctionAdmin',
41 html: '<p>Some info in here.</p>',
42 iconCls: 'info',
43 listeners: {
44 //beforerender: function () { alert('beforerender'); },
45 //beforecollapse: function () { alert('beforecollapse'); },
46 //beforeexpand: function () { alert('beforeexpand'); },
47 expand: function () { Ext.MessageBox.alert('消息', '系统管理展开了!'); }
48 }
49 }]
50 });
4、App.MainFunctionTree
1 Ext.define('FunctionTreeStore', {
2 extend: 'Ext.data.TreeStore',
3 autoLoad: true,
4 proxy:{
5 type: 'direct',
6 //设置Direct服务函数
7 directFn: MyApp.TestAction.getTree,
8 paramOrder: ['node']
9 },
10 root:{
11 expanded : true
12 }
13 });
14 Ext.define('App.MainFunctionTree',{
15 extend:'Ext.tree.Panel',
16 alias:'widget.FunctionTree',
17 store: Ext.create('FunctionTreeStore'),
18 height: 350,
19 width: 600,
20 rootVisible: false
21
22 });
服务器Direct照以往的写就ok,利用DirectHandler.Configure(DirectProvider provider, IEnumerable<object> items)加载相应的服务Class
5、Api.ashx
1 <%@ WebHandler Language="C#" Class="Api" %>
2
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using System.Web;
7 using Ext.Direct;
8
9 public class Api : DirectHandler
10 {
11
12 public override string ProviderName
13 {
14 get
15 {
16 return "Ext.app.USER_API";
17 }
18 }
19
20 public override string Namespace
21 {
22 get
23 {
24 return "MyApp";
25 }
26 }
27
28 protected override void ConfigureProvider(DirectProvider provider)
29 {
30 this.Configure(provider, new object[] { new CheckLogin(),new TestAction() });
31 }
32
33 }
6、随手写的生成树状图的cs,怎一个烂字了得……
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using Ext.Direct;
6 using Newtonsoft.Json;
7 using Newtonsoft.Json.Linq;
8 using System.Web.SessionState;
9 using System.Web.Security;
10
11 /// <summary>
12 ///CheckLogin 的摘要说明
13 /// </summary>
14 [DirectAction]
15 public class TestAction
16 {
17
18 [DirectMethod]
19 public JArray getTree(string id)
20 {
21 JArray data = new JArray();
22
23 data.Add(new JObject(
24 new JProperty("id", id+id),
25 new JProperty("text", "tes"),
26 new JProperty("leaf", false)
27 ));
28
29
30 return data;
31 }
32 }
经测试,以上组合方式可以正常运行,应用组件化编程和面向对象技术可以使思路更加清晰,使用动态加载可以提高访问速度,使用Direct可以达到MVC的效果。
接下来将使用这些技术制作一个完整的例子,欢迎讨论,欢迎拍砖