设计思路:
下载mvc sample 并理解其设计文章
2.直接在框架中进行开发,首先需要改的就是viewport,定义框架,主要包括头部的工具条栏与侧边
.
App.views.Viewport = Ext.extend(Ext.Panel, {
fullscreen: true,
layout: 'card',
cardSwitchAnimation: 'fade',
dockedItems: [
{
dock : 'top',
xtype : 'toolbar',
cls : 'x-toolbar-dark',
baseCls: 'x-toolbar',
height : 45,
itemId : 'newQueryForm',
items: [
{ iconMask: true, ui: 'back',text: 'Back',itemId: 'backBtn', },
{ iconMask: true, ui: 'home',text:'Home',itemId: 'homeBtn', },
{xtype: 'spacer'},
{ iconMask: true, ui: 'query',text:'Tab',itemId: 'tabQuery',}
]
},
{
dock : 'left',
xtype: 'searchBar',
width: 400
}
],
});
由于头工具栏与侧边栏位置将定死,现在我们可以在余下的空间内对页面进行配置。
3.我们要做的就是对工具栏的几个button进行配置(app.js)
Ext.regApplication({
name: 'App',
defaultUrl: 'Home/index',
launch: function()
{
//Array delete item and delete memory
this.viewport = new App.views.Viewport();
this.viewport.query('#backBtn')[0].setHandler(function(){
var searchesStore = Ext.getStore('Searches');
//var searchList = Ext.getCmp('searchesList');
var i = parentArray.length;
if (i == 0) {
return;
}
else {
if (parentArray[i - 1] == 1) {
searchesStore.getProxy().url = allMetricUrl;
parentArray.removeMemory(i - 1);
searchesStore.read();
}
else {
searchesStore.getProxy().url = childMetricUrl + parentArray[i - 1];
parentArray.removeMemory(i - 1);
searchesStore.read();
}
}
});
this.viewport.query('#homeBtn')[0].setHandler(function(){
//Ext.ControllerManager.get('Search').index();
var searchesStore = Ext.getStore('Searches');
searchesStore.getProxy().url = allMetricUrl;
parentArray=new Array();
searchesStore.read();
searchesStore.load();
});
由于是应用最先执行的js,我们可以在这里定义全局变量,当然最主要的,我们可以通过
this.viewport.query('#backBtn')[0]
作用主要用来刷侧边栏(后退,回到根目录)。
4.开始对controller进行设计,首先要定义的就是通过app.js中看到的默认路径,在controller中定义一个index的action
defaultUrl: 'Home/index',
于是乎我们看到:
Ext.regController('Home', {
// index action
index: function(options)
{
var store=Ext.getStore('Charts');
if(!store.first())
{
Ext.dispatch({
controller: "Home",
action : "about",
//instance : first,
historyUrl: "Home/about"
});
}
else{
if ( ! this.indexView)
{
this.indexView = this.render({
xtype: 'HomeIndex',
});
}
this.application.viewport.setActiveItem(this.indexView, options.animation);
}
},
// about action
about: function()
{
if ( ! this.aboutView)
{
this.aboutView = this.render({
xtype: 'HomeAbout',
});
}
this.application.viewport.setActiveItem(this.aboutView);
},
});
从代码中我们看到lz试图通过判断数据源中的数据是否存在,来决定逻辑的方向:数据源中如果存在数据,index action将执行渲染页面,并展示的操作,
如果数据源中没有获得任何数据,程序将跳转至about页面,系统将把about页面展示出来。
5.设计展示的页面,这里我们假定设计一个line图表嵌套在chart.pannel中,在嵌套在tab.pannel中
代码:
var lineChart = new Ext.chart.Chart({ title: 'Line', iconCls: 'line', cls: 'chartpanel', interactions: ['reset', { type: 'panzoom', axes: { right: {} } },{ type: 'iteminfo', gesture: 'tap', listeners: { 'show': function(me, item, panel) { var storeItem = item.storeItem; panel.update('<ul><li><b>DateTime:</b> ' + storeItem.get('DateTime') + '</li><li><b>Value: </b> ' + storeItem.get('m1') + '</li></ul>'); } } }], animate: false, store: 'Charts', axes: [{ type: 'Numeric', position: 'right', minimum: 0, adjustMinimumByMajorUnit: 0, fields: ['m1'], title: 'Points', grid: { odd: { stroke: '#777' }, even: { stroke: '#555' } } }, { type: 'Category', position: 'bottom', fields: ['DateTime'], title: 'DateTime', label: { rotate: { degrees: 45 } } }], // legend: { // position: Ext.is.Phone ? 'left' : 'top' // }, theme: 'Energy', series: [{ type: 'line', highlight: false, showMarkers: false, fill: true, smooth: true, axis: 'right', xField: 'DateTime', yField: 'm1', title: ['m1'] } }); var lineChartPanel = new Ext.chart.Panel({ title: 'LineMetricName', id:'indexLine', layout: 'fit', iconCls: 'bar', dockedItems: { iconMask: true, ui: 'setting', text:'Setting', itemId: 'settingBtn', handler: showSetting }, items:[lineChart] });
App.views.HomeIndex = Ext.extend(Ext.TabPanel, { fullscreen:false, id:'homeIndex', dockedItems: [ toolbar1,toolbar2 ], tabBar: { dock: 'bottom', hidden:true, layout: { pack: 'center' } }, cardSwitchAnimation: { type: 'slide' }, type: 'dark', sortable: false, items: [lineChartPanel] //barChart, pieChart,scatterChart,areaChart] }); Ext.reg('HomeIndex', App.views.HomeIndex);
6.对数据源的定义,lz用的是从wcf叫数据,这里构建一个modelExt.regModel("Search", { //after replace field,the right pannel will not show(auto loading will no working) // fields: [ // {name: "id", type: "int"}, // {name: "query", type: "string"} // ], fields: [{ name: 'MetricId', type: 'int' }, { name: 'HostName', type: 'string' }, { name: 'MetricName', type: 'string' }, { name: 'ParameterId', type: 'int' }, { name: 'StatusId', type: 'int' }, { name: 'UserDomain', type: 'string' }, { name: 'ParentNodeId', type: 'int' }, { name: 'NodeId', type: 'int' }, { name: 'HasChildren', type: 'int' }], proxy: { id : 'twitter-searches', url: 'http://emite-pc:5555/exampleJsonpService/Nodes', type: 'scripttag', extraParams: { userName: 'admin', userDomain: 'admin' }, reader: { root: '' } } });
如此可以在sencha-toucha1.1中request jsonp的数据源,除此以外我们还需要一个数据仓库,供我们存储request成功的数据
Ext.regStore('Searches', { model: 'Search', autoLoad: true });
如此便可将store绑定到图表形成我们上面的界面