本文对Ext.NET使用中的常见问题进行收集,有新问题或补充的请在下方留言,内容随之持续更新,谢谢。需要大家的共同努力。
Ext.Net官方Demo
Ext.Net官方API
Ext.Net社区版源码下载
ExtJS官方站点包括Demo和API
Q:前台js中怎么判断GridPanel里面是否有数据?
A:
1
2
3
4
5
6
7
|
var rowsCount = gridPanel1.store.getTotalCount(); var hasData = Boolean((rowsCount) > 0); if (!hasData) { Ext.MessageBox.alert('温馨提示', '请增加明细信息!'); return false; } |
Q:如何执行删除前确认?
A:
1
2
3
4
5
6
7
8
|
< ext:Button runat = "server" ID = "btnDelete" Text = "删除" Icon = "Delete" Disabled = "true" > < DirectEvents > < Click OnEvent = "btnDelete_Click" > < Confirmation ConfirmRequest = "true" Message = "删除后不可恢复,确定删除所选的数据吗?" Title = "温馨提示" /> < EventMask ShowMask = "true" /> </ Click > </ DirectEvents > </ ext:Button > |
Q:如何后台遍历GridPanel中的数据?
A:
参见
- http://examples.ext.net/#/GridPanel/Selection_Models/Submitting_Values/
- http://examples.ext.net/#/GridPanel/Selection_Models/Row_Selection/
要点,前台提取数据,后台解析JSON字符串。
前台:
1
2
3
4
5
6
7
8
9
10
11
|
< Buttons > < ext:Button runat = "server" Text = "Submit selection" > < DirectEvents > < Click OnEvent = "SubmitSelection" > < ExtraParams > < ext:Parameter Name = "Values" Value = "Ext.encode(#{GridPanel1}.getRowsValues({selectedOnly : true}))" Mode = "Raw" /> </ ExtraParams > </ Click > </ DirectEvents > </ ext:Button > </ Buttons > |
后台:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
protected void SubmitSelection(object sender, DirectEventArgs e) { string json = e.ExtraParams["Values"]; if (string.IsNullOrEmpty(json)) { return; } //XML will be represent as //< records > // < record >< Name >Alcoa Inc</ Name >< Price >29.01</ Price >< Change >0.42</ Change >< PctChange >1.47</ PctChange ></ record > // ... // < record >...</ record > //</ records > XmlNode xml = JSON.DeserializeXmlNode("{records:{record:" + json + "}}"); foreach (XmlNode row in xml.SelectNodes("records/record")) { string name = row.SelectSingleNode("Name").InnerXml; string price = row.SelectSingleNode("Price").InnerXml; string change = row.SelectSingleNode("Change").InnerXml; string pctChange = row.SelectSingleNode("PctChange").InnerXml; //handle values } List< Company > companies = JSON.Deserialize< List <Company>>(json); foreach (Company company in companies) { string name = company.Name; double price = company.Price; double change = company.Change; double pctChange = company.PctChange; //handle values } Dictionary< string , string>[] companies1 = JSON.Deserialize< Dictionary <string, string>[]>(json); foreach (Dictionary< string , string> row in companies1) { string name = row["Name"]; string price = row["Price"]; string change = row["Change"]; string pctChange = row["PctChange"]; //handle values } this.ResourceManager1.AddScript("Ext.Msg.alert('Submitted', 'Please see source code how to handle submitted data');"); } |
1
|
|
Q: GridPanel怎么实现服务器端分页、排序、查询?
A:
学习分页之前不得不提的是Ext.Net提供的一个很有用的集合类Ext.Net.Paging<T> 类,有兴趣的可以去看看API 或 下载源码看看。
以下是官方给出的各种服务器端分页方式:
-
HttpHandler
采用XML为数据,以Store的HttpProxy实现服务器端数据查询、分页及排序,与服务器GET方法交互,服务器返回Ext.Net.Paging<T>实例的JSON串;
<Proxy> <ext:HttpProxy Method="GET" Url="http://www.cnblogs.com/Shared/PlantHandler.ashx" /> </Proxy>
-
JSON WebService
采用XML为数据,以Store的HttpProxy调用远端公开的WebService方法实现远端数据查询、分页及排序,与服务器POST方法交互,服务器返回Ext.Net.Paging实例;
-
local paging
官方Demo上面列出了本地分页的优势:
A.本地分页(PS:这也是个优势);
B.可以使用一次请求提交GridPanel的所有页的数据;
C.如果你在GridPanel的多个页上编辑数据,可以在一次请求时保存,且在多页之间切换时不会丢失编辑的数据;
D.在所有页面获取用户选择的数据;
E.Navigate on page by record(PS:我的理解是,当选择某条记录时,可自动跳转到某页,待修正). -
Local Paging for Remote Data
这是本地分页与远端分页的组合产物,思路很强大,值得借鉴;
-
Multiple Sorting
多条件排序的一个Demo,值得一提的是,本例用了ToolbarDroppable插件,实现了将任意列头移动至排序栏(试试将Name列拖动至上方工具栏中Cool:)!)
-
With ObjectDataSource
本例用ObjectDataSource为Store提供数据,服务器端分页、查询、排序,DAO采用Linq to sql ,采用最新的Entity Framework或许会更好:)
-
XML WebService
调用WebService公开的方法实现服务器端数据查询、分页及排序,前面几个都认真看了的话,此处可跳过。
-
一个相对完整的服务器端分页Demo
-
群友提供的一个服务器端分页Demo
使用数据库中储存过程的方式与GridPanel配合完成,每次访问仅读出分页的数据。by-无情,QQ:873***901
A.前端aspx文件
i.store定义
<ext:Store ID="StoreQGD" runat="server" AutoLoad="true" RemoteSort="true" OnRefreshData="StoreQGD_Refresh"> <reader> <ext:JsonReader IDProperty="mKey"> <Fields> <ext:RecordField Name="mKey" Type="Int"/> <ext:RecordField Name="tKey" Type="String" /> <ext:RecordField Name="zlkey" Type="String" /> <ext:RecordField Name="nCorr" Type="String"/> <ext:RecordField Name="HUID" Type="String" /> <ext:RecordField Name="tDtm" Type="Date" /> <ext:RecordField Name="State" Type="String"/> <ext:RecordField Name="LEUID" Type="String" /> <ext:RecordField Name="LEDtm" Type="Date" /> <ext:RecordField Name="Remark" Type="String"/> </Fields> </ext:JsonReader> </reader> <proxy> <ext:PageProxy></ext:PageProxy> </proxy> <baseparams> <ext:Parameter Name="sort" Value="" /> <ext:Parameter Name="dir" Value="" /> </baseparams> <sortinfo field="mKey" direction="DESC" /> </ext:Store>
ii.Gridpanel定义
<ext:GridPanel ID="GridPanelQGD" runat="server" StoreID="StoreQGD"> <columnmodel id="ColumnModel3" runat="server"> <Columns> <ext:Column Header="ID" DataIndex="mKey" Hidden="true" Align="Center"/> <ext:Column Header="请购单号" DataIndex="tKey" Align="Center"/> <ext:Column Header="制令号" DataIndex="zlkey" Align="Center"/> <ext:Column Header="所属客户" DataIndex="nCorr" Align="Center"/> <ext:Column Header="经手人" DataIndex="HUID" Align="Center"/> <ext:Column Header="生效时间" DataIndex="tDtm" Align="Center"> <Renderer Fn="Ext.util.Format.dateRenderer('Y/m/d')" /> </ext:Column> <ext:Column Header="状态" DataIndex="State" Align="Center"> <Renderer Fn="State" /> </ext:Column> <ext:Column Header="更新用户" DataIndex="LEUID" Align="Center"/> <ext:Column Header="更新日期" DataIndex="LEDtm" Align="Center"> <Renderer Fn="Ext.util.Format.dateRenderer('Y/m/d')" /> </ext:Column> <ext:Column Header="备注" DataIndex="Remark" Width="200" Align="Center"/> </Columns> </columnmodel> <plugins> <ext:GridFilters runat="server" ID="GridFilters3" Local="false"> <Filters> <ext:NumericFilter DataIndex="mKey"/> <ext:StringFilter DataIndex="tKey"/> <ext:StringFilter DataIndex="zlkey"/> <ext:StringFilter DataIndex="nCorr" /> <ext:StringFilter DataIndex="HUID" /> <ext:DateFilter DataIndex="tDtm"> <DatePickerOptions runat="server" TodayText="Now"/> </ext:DateFilter> <ext:ListFilter DataIndex="State" Options="作废,待审核,已审核,记账,结案"/> <ext:StringFilter DataIndex="LEUID"/> <ext:DateFilter DataIndex="LEDtm"> <DatePickerOptions runat="server" TodayText="Now"/> </ext:DateFilter> <ext:StringFilter DataIndex="Remark" /> </Filters> </ext:GridFilters> </plugins> <loadmask showmask="true" /> <selectionmodel> <ext:RowSelectionModel ID="RowSelectionModel2" runat="server"> </ext:RowSelectionModel> </selectionmodel> <bottombar> <ext:PagingToolbar ID="PgbQGD" runat="server" PageSize="10" StoreID="StoreQGD"> </ext:PagingToolbar> </bottombar> </ext:GridPanel>
B.后端aspx.cs文件
protected void StoreQGD_Refresh(object sender, StoreRefreshDataEventArgs e) { string conditions = e.Parameters[GridFilters3.ParamPrefix];//GridFilters3是GridFilters是id int Pagesize = PgbQGD.PageSize; int Currentpage = e.Start / Pagesize + 1; int count = 0; string fldName = e.Parameters["sort"]; string OrderType = e.Parameters["dir"]; if (!string.IsNullOrEmpty(conditions)) { string m = MyBean.Sql.DataQuery.GetConditonSQL(conditions);//过滤条件 DataTable dt = MyBean.Sql.DataQuery.Pagination("View_Web_QGD", m, fldName, Currentpage, Pagesize, OrderType, out count); e.Total = count; this.StoreQGD.DataSource = dt; this.StoreQGD.DataBind(); } else { DataTable dt = MyBean.Sql.DataQuery.Pagination("View_Web_QGD", "", fldName, Currentpage, Pagesize, OrderType, out count); e.Total = count; this.StoreQGD.DataSource = dt; this.StoreQGD.DataBind(); } } /// <summary> /// 根据filter的条件进行过滤 /// </summary> /// <param name="conditions"></param> /// <returns></returns> public static string GetConditonSQL(string conditions) { string _con = ""; if (!string.IsNullOrEmpty(conditions)) { FilterConditions fc = new FilterConditions(conditions); foreach (FilterCondition condition in fc.Conditions) { Comparison comparison = condition.Comparison; string field = condition.Name; FilterType type = condition.FilterType; switch (condition.FilterType) { case FilterType.Date: if (comparison.ToString() == "Lt") _con += "and " + field + " < '" + condition.Value + "'"; else if (comparison.ToString() == "Gt") _con += "and " + field + " > '" + condition.Value + "'"; else _con += "and " + field + " = '" + condition.Value + "'"; break; case FilterType.Numeric: if (comparison.ToString() == "Lt") _con += "and " + field + " < '" + condition.Value + "'"; else if (comparison.ToString() == "Gt") _con += "and " + field + " > '" + condition.Value + "'"; else _con += "and " + field + " = '" + condition.Value + "'"; break; case FilterType.String: _con += "and " + field + " like '%" + condition.Value + "%' "; break; case FilterType.List: if (condition.ValuesList[0].ToString() == "作废") _con += "and " + field + " = ' 5 '"; else if (condition.ValuesList[0].ToString() == "待审核") _con += "and " + field + " = '10'"; else if (condition.ValuesList[0].ToString() == "已审核") _con += "and " + field + " = '15'"; else if (condition.ValuesList[0].ToString() == "记账") _con += "and " + field + " = '20'"; else _con += "and " + field + " = '25'"; break; } } _con = _con.Substring(3); } return _con; }
C.存储过程SQL
create procedure [dbo].[fnWebPage] ( --1,参数的括号可要可不要,有默认值的参数,在调用的时候,可以不写出来 --2,调用: --declare @i int --exec fnWebPage 'list','id,title','id',3,4,1,'classid=6',@i out @tblName varchar(100), -- 表名 @fldCow varchar(100)='*', -- 要查询的列 @fldName varchar(255), -- 排序列 @PageSize int , -- 页尺寸 @PageIndex int = 1, -- 页码 @OrderType varchar(50), -- 设置排序类型, 1则降序 @strWhere varchar(Max) = '', -- 查询条件 (注意: 不要加 where) @count int output --输出符合条件的记录的总数 ) AS declare @strSQL varchar(1000); -- 主语句 declare @strOrder varchar(500) ; -- 排序类型 declare @strTmp varchar(100) ; --临时变量 declare @endIndex int; -- 结束的索引 declare @startIndex int; -- 开始的索引 declare @countSql nvarchar(500); --查询记录总数的sql --得到索引 set @startIndex=(@PageIndex-1)*@PageSize + 1;--注意,这里要加1 set @endIndex=@PageIndex*@PageSize; --生成排序语句 --为了多表联合查询,这里要把表名字和排序字段的[]去掉- if @OrderType != 'ASC' set @strOrder = ' order by ' + @fldName + ' DESC' else set @strOrder = ' order by ' + @fldName + ' ASC' set @strSQL = '(select top ' + ltrim(str(@endIndex)) + ' '+@fldCow+',' + 'row_number() over ('+ @strOrder +') as rownumber from ' + @tblName + '' ; set @countSql= 'select @count=count('+@fldName+') from '+ @tblName ; if @strWhere! = '' begin set @strSQL =@strSQL+ ' where ('+ @strWhere + ') '; set @countSql=@countSql + ' where ('+ @strWhere + ') '; end set @strSQL =@strSQL+ ') as tblTmp' --得到记录总数 set @countSql=N'select @count=count(*) from ' + @tblName; if @strWhere! = '' set @countSql=@countSql+ N' where ' + @strWhere; EXEC sp_executesql @countSql,N'@count int out',@count out set @strSQL = 'select * from ' + @strSQL + ' where rownumber between ' + ltrim(str(@startIndex)) + ' and ' + ltrim(str(@endIndex)); --执行主语句 set nocount on -- 防止显示有关受影响的行数的信息 exec (@strSQL) --print @strSQL
最后奉上Ext.Net.Paging<T>源码
using System.ComponentModel; using System.Collections.Generic; namespace Ext.Net { /// <summary> /// /// </summary> [Description("")] public partial class Paging<T> { private List<T> data; private int totalRecords; /// <summary> /// /// </summary> [Description("")] public Paging() { } /// <summary> /// /// </summary> [Description("")] public Paging(IEnumerable<T> data, int totalRecords) { this.data = new List<T>(data); this.totalRecords = totalRecords; } /// <summary> /// /// </summary> [Description("")] public List<T> Data { get { return data; } set { data = value; } } /// <summary> /// /// </summary> [Description("")] public int TotalRecords { get { return totalRecords; } set { totalRecords = value; } } } }
Q:EXT.NET中如何在执行完一段后台代码后,再执行一段前台js?
A:
两个静态方法:
1
2
3
4
5
6
7
|
Ext.Net.X.AddScript(string script);//script:参数为要执行的脚本 Ext.Net.X.AddScript(string script, params object[] params);//script:参数为要执行的脚本,params:参数; Ext.Net.X.Call(string functionName);//functionName:要调用的js方法名称; Ext.Net.X.Call(string functionName, params object[] params);//functionName:要调用的js方法名称;params:参数; |