先从这里下载ExtJs最新的源码包,将其中的adapter和resource文件夹及几个js脚本添加到新建的mvc项目中,项目文件结构如下图:
下图是LINQ实体对象的结构
最重要的是下面的JS脚本,将这个脚本文件引用到需要展示数据的视图页面
/*!
* NameData JavaScript Library v1.0.0
* http://www.cnpc.ac.cn/
* Date: Mon Jan 25 19:43:33 2010 -0500
*/
Ext.BLANK_IMAGE_URL = '../../images/default/s.gif';
Ext.namespace('myNameSpace');
myNameSpace.myModule = function () {
var ds;
var grid;
var colModel;
var myRecordObj;
var myReader;
var primaryKey = 'Id';
var setupDataSource = function () {
myRecordObj = Ext.data.Record.create([
{ name: 'Id', type: 'string' },
{ name: 'CanonicalString', type: 'string' },
{ name: 'NameAuthor', type: 'string' },
{ name: 'Reference', type: 'string' },
{ name: 'PublishedYear', type: 'string' },
{ name: 'ParentId', type: 'string' },
{ name: 'Rank', type: 'string' },
{ name: 'Group', type: 'string' }
]);
myReader = new Ext.data.JsonReader(
{
root: 'results',
totalProperty: 'total',
id: primaryKey
},
myRecordObj
);
ds = new Ext.data.GroupingStore({
proxy: new Ext.data.HttpProxy({
url: '/Name/ListName',
method: 'POST'
}),
reader: myReader,
remoteSort: true
});
}; //end setupDataSource
var getColumnModel = function () {
if (!colModel) {
colModel = new Ext.grid.ColumnModel([
{
header: '编号',
dataIndex: 'Id',
sortable: true,
width: 50
},
{
header: '名称',
dataIndex: 'CanonicalString',
sortable: true,
width: 50
},
{
header: '作者',
dataIndex: 'NameAuthor',
sortable: true,
width: 50
},
{
header: '文献',
dataIndex: 'Reference',
sortable: true,
width: 50
},
{
header: '年代',
dataIndex: 'PublishedYear',
sortable: true,
width: 50
},
{
header: 'ParentId',
dataIndex: 'ParentId',
sortable: true,
width: 50
},
{
header: '分类等级',
dataIndex: 'Rank',
sortable: true,
width: 50
},
{
header: '类群',
dataIndex: 'Group',
sortable: true,
width: 50
}
]); //end colModel
} //end if colModel
return colModel;
} //end getColumnModel
var buildGrid = function () {
function addRecord() {
var c_Id = new Ext.form.TextField
({
fieldLabel: '编号',
name: 'Id',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var c_CanonicalString = new Ext.form.TextField
({
fieldLabel: '名称',
name: 'CanonicalString',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var c_NameAuthor = new Ext.form.TextField
({
fieldLabel: '作者',
name: 'NameAuthor',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var c_Reference = new Ext.form.TextField
({
fieldLabel: '文献',
name: 'Reference',
width: '200',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var c_PublishedYear = new Ext.form.TextField
({
fieldLabel: '年代',
name: 'PublishedYear',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var c_ParentId = new Ext.form.TextField
({
fieldLabel: 'ParentId',
name: 'ParentId',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var c_Rank = new Ext.form.TextField
({
fieldLabel: 'Rank',
name: 'Rank',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var c_Group = new Ext.form.TextField
({
fieldLabel: 'Group',
name: 'Group',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var newForm = new Ext.FormPanel({
bodyStyle: 'padding: 8px',
url: '/Name/New',
items: [
c_Id,
c_CanonicalString,
c_NameAuthor,
c_Reference,
c_PublishedYear,
c_ParentId,
c_Rank,
c_Group
]
});
var newWin = new Ext.Window({
title: '添加新名字',
width: 390,
height: 500,
minWidth: 300,
minHeight: 250,
layout: 'fit',
plain: true,
bodyStyle: 'padding:5px;',
buttonAlign: 'center',
items: newForm,
buttons: [{
text: '保存',
handler: function () {
if (newForm.form.isValid()) {
newForm.form.submit({
waitMsg: 'In processing',
failure: function (form, action) {
Ext.MessageBox.alert('Error Message', action.result.errorInfo);
},
success: function (form, action) {
Ext.MessageBox.alert('Success:', action.response.responseText);
refreshGrid();
newWin.hide();
}
});
}
else {
Ext.MessageBox.alert('Errors', 'Please fix the errors noted.');
}
}
}, {
text: '清除',
handler: function () {
newForm.getForm().reset();
}
}]
});
newWin.on('minimize', function () {
newWin.toggleCollapse();
});
newWin.show();
}; // end addRecord
function deleteRecord(btn) {
if (btn == 'yes') {
var selectedKeys = grid.selModel.selections.keys;
Ext.Ajax.request({
waitMsg: 'Saving changes...',
url: '/Name/Delete',
params: {
data: selectedKeys
},
callback: function (options, success, response) {
if (success) {
Ext.MessageBox.alert('OK', response.responseText);
var json = Ext.util.JSON.decode(response.responseText);
Ext.MessageBox.alert('OK', json.del_count + ' record(s) deleted.');
} else {
Ext.MessageBox.alert('Sorry, please try again. [Q304]', response.responseText);
}
},
failure: function (response, options) {
Ext.MessageBox.alert('Warning', 'Oops...');
},
success: function (response, options) {
refreshGrid();
}
});
}
};
function handleDelete() {
var selectedKeys = grid.selModel.selections.keys;
if (selectedKeys.length > 0) {
Ext.MessageBox.confirm('Message', 'Do you really want to delete selection?', deleteRecord);
}
else {
Ext.MessageBox.alert('Message', 'Please select at least one item to delete');
}
}; // end handleDelete
function toggleDetails(btn, pressed) {
var view = grid.getView();
view.showPreview = pressed;
view.refresh();
}
function refreshGrid() {
ds.reload(); //
};
grid = new Ext.grid.GridPanel({
clicksToEdit: 2,
colModel: getColumnModel(),
height: 350,
iconCls: 'icon-grid',
id: 'myGridID',
loadMask: true,
selModel: new Ext.grid.RowSelectionModel({ singleSelect: false }),
store: ds,
stripeRows: true,
title: '名称列表',
width: 900,
bbar: new Ext.PagingToolbar({
pageSize: myNameSpace.myModule.perPage,
store: ds,
displayInfo: true,
displayMsg: 'Displaying topics {0} - {1} of {2}',
emptyMsg: "No data to display",
items: [
'-', {
pressed: true,
enableToggle: true,
text: 'Show Preview',
cls: 'x-btn-text-icon details',
toggleHandler: toggleDetails
}]
}),
tbar: [
{
text: '添加',
tooltip: '添加一个新名字',
//iconCls: 'add',
handler: addRecord
}, '-', //add a separator
{
text: '删除',
tooltip: 'Click to Delete selected row(s)',
//function to call when user clicks on button
//iconCls: 'remove',
handler: handleDelete
}, '-',
{
text: '刷新',
tooltip: 'Click to Refresh the table',
//iconCls: 'icon-grid',
handler: refreshGrid
}
],
view: new Ext.grid.GroupingView({
forceFit: true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
})
}); //end grid
grid.on('rowdblclick', function (grid, rowIndex, e) {
var id = ds.data.items[rowIndex].id;
var u_Id = new Ext.form.TextField
({
fieldLabel: '编号',
name: 'Id',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var u_CanonicalString = new Ext.form.TextField
({
fieldLabel: '名称',
name: 'CanonicalString',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var u_NameAuthor = new Ext.form.TextField
({
fieldLabel: '作者',
name: 'NameAuthor',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var u_Reference = new Ext.form.TextField
({
fieldLabel: '文献',
name: 'Reference',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var u_PublishedYear = new Ext.form.TextField
({
fieldLabel: '年代',
name: 'PublishedYear',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var u_ParentId = new Ext.form.TextField
({
fieldLabel: 'ParentId',
name: 'ParentId',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var u_Rank = new Ext.form.TextField
({
fieldLabel: '分类等级',
name: 'Rank',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var u_Group = new Ext.form.TextField
({
fieldLabel: '类群',
name: 'Group',
width: '180',
maskRe: /([a-zA-Z0-9\s]+)$/
});
var updateForm = new Ext.FormPanel({
bodyStyle: 'padding: 8px',
url: '/Name/Edit',
reader: new Ext.data.JsonReader(
{ root: 'results' },
[
{ name: 'Id', type: 'string' },
{ name: 'CanonicalString', type: 'string' },
{ name: 'NameAuthor', type: 'string' },
{ name: 'Reference', type: 'string' },
{ name: 'PublishedYear', type: 'string' },
{ name: 'ParentId', type: 'string' },
{ name: 'Rank', type: 'string' },
{ name: 'Group', type: 'string' }
]),
items: [
u_Id,
u_CanonicalString,
u_NameAuthor,
u_Reference,
u_PublishedYear,
u_ParentId,
u_Rank,
u_Group
]
});
updateForm.form.load({
url: '/Name/LoadName',
params: { id: id },
waitMsg: 'Loading'
});
var window = new Ext.Window({
title: 'Edit Existing Name',
width: 390,
height: 500,
minWidth: 300,
minHeight: 250,
layout: 'fit',
plain: true,
bodyStyle: 'padding:5px;',
buttonAlign: 'center',
items: updateForm,
buttons: [{
text: '保存',
handler: function () {
if (updateForm.form.isValid()) {
updateForm.form.submit({
params: { id: id },
waitMsg: 'In processing',
failure: function (form, action) {
Ext.MessageBox.alert('Error Message', action.result.errorInfo);
},
success: function (form, action) {
Ext.MessageBox.alert('Confirm', action.response.responseText);
window.hide();
ds.load({ params: { start: 0, limit: 10} });
}
});
}
else {
Ext.MessageBox.alert('Errors', 'Please fix the errors noted.');
}
}
},
{
text: '取消',
handler: function () { window.hide(); }
}]
});
window.show();
});
} //end function buildGrid
var renderGrid = function () {
grid.render('NamesList');
}; //end function renderGrid
var loadStore = function () {
ds.load({
params: {
start: 0,
limit: myNameSpace.myModule.perPage
}
});
grid.getSelectionModel().selectFirstRow();
};
return {
perPage: 30,
init: function () {
this.getMyGrid();
}, //end of init method
getMyGrid: function () {
Ext.QuickTips.init();
setupDataSource();
buildGrid();
renderGrid();
loadStore();
},
getDataSource: function () {
return ds;
}
}//end of return
} ();
Ext.onReady(myNameSpace.myModule.init, myNameSpace.myModule, true);
NameController的两个重要方法
public void LoadName()
{
string id = Request.Form["id"];
string message = string.Empty;
cnpcDataContext db = new cnpcDataContext();
var query = from n in db.Names
where n.Id.ToString() == id
select new
{
n.Id,
n.CanonicalString,
n.NameAuthor,
n.Reference,
n.PublishedYear,
n.ParentId,
n.Rank,
n.Group
};
JavaScriptSerializer serializer = new JavaScriptSerializer();
message = "{\"results\":" + serializer.Serialize(query.ToList()) + "}";
Response.Write(message);
}
public void ListName(int limit, int start, string dir, string sort)
{
string message = string.Empty;
cnpcDataContext db = new cnpcDataContext();
var query = from n in db.Names
select new
{
n.Id,
n.CanonicalString,
n.NameAuthor,
n.Reference,
n.PublishedYear,
n.ParentId,
n.Rank,
n.Group
};
int totalRecords = query.ToList().Count;
JavaScriptSerializer serializer = new JavaScriptSerializer();
var list = query.Skip(start).Take(limit);
message = "{\"total\": \"" + totalRecords + "\", \"results\":" + serializer.Serialize(list.ToList()) + "}";
Response.Write(message);
}