在处理一些大量数据时,往往用到查询,但是大量数据不适合全部查出,最好是分页查出,分页时还想有些参数过滤下,如下效果
Ext.define('项目包名.路径.store类名', {
extend: 'Ext.data.Store',
alias: 'store.remoteDemo',//指定store的别名
idProperty: '列名',
fields: [
//fields配置参数
],
remoteSort: true,//重要 指定远端排序
remoteFilter: true,//!!重要 指定远端过滤
pageSize:20,//指定一页行数 默认是25
proxy: {
type: 'ajax',//指定代理为ajax 通过服务端处理
api: 'url地址'
}
});
例如grid控件:在grid控件上放个可输入的文本框 用于远端查询过滤
{
xtype:'grid',
items:[
{
xtype:'toolbar',
itemId:'tbar',
docked: 'top',
items:[
{
xtype:'textfield',
name:'paramA',//自定义要查询的参数的key
role: 'filter',//可以设置一个role字段来标识
placeholder:'查询条件1'
},
{
xtype:'textfield',
name:'paramB',
role: 'filter',
placeholder:'查询条件2'
},
{
xtype:'button',
text:'查询',
handler:'onSearch'//当点击查询时调用store的过滤查询
}
]
}
],
plugins: {
gridpagingtoolbar: true//使用分页插件 必备
},
store:{
type:'remoteDemo'//指定第一步配置的store
},
}
设置store查询方法处理
onSearch() {
let grid = 通过lookup或其他查询器找到grid控件,
store = grid.getStore(),//获取store
filters = [];
let vals;
const bar = grid.down('#tbar'),
fields = bar.query('field[role=filter]');//通过查询器获取用于输入过滤条件的控件
vals = {};
fields.forEach(field => {
vals[field.getName()] = field.getValue();
});
for (var k in vals) {
if (vals.hasOwnProperty(k) && !Ext.isEmpty(vals[k])) {
filters.push({ //以键值对的形式 组成后端所需的 过滤json
property: k,
value: vals[k]
});
}
}
store.suppressNextFilter = true;
store.clearFilter(true);//清除上次的过滤 防止数据错误
store.setFilters(filters);//加载新的过滤条件
store.suppressNextFilter = false;
store.loadPage(1);//加载第一页
}
后端用的C# 自己可以参照改造,反正前端传回的值都是 json格式的
定义好一个PageQueryXX方法名的方法(为何要PageQuery打头? ——容易辨识)
public StoreResult PageQuerySqlLog(StoreParams storeParams)//使用StoreResult 作为返回类型,StoreParams 类型用于接收store的各种参数
{
string where = @"";
List < SqlParameter > parameters = new List();
if (storeParams.filter != null) {
foreach(StoreFilter filter in storeParams.filter)//读取store的filter里的json信息
{
if (string.IsNullOrEmpty(filter.value)) continue;
if (filter.property == "paramA") {
where += @" and T.表列名 like '%' + @参数名A + '%'";//拼接sql查询语句
parameters.Add(new SqlParameter("@参数名A", filter.value));//为参数赋值
}
else if (filter.property == "paramB") {
where += @" and T.表列名 >= @DateFr";//时间格式的demo
SqlParameter pa = new SqlParameter("@DateFr", SqlDbType.DateTime);
pa.Value = DateTime.Parse(filter.value);
parameters.Add(pa);
}
}
}
//拼装分页查询的子查询语句
string innerSql = string.Format(@" select 列名A,列名B from 表名 T where { 0 } ", where);//把动态拼接的where条件塞入
DataTable dt = null;
//拼接分页查询
//!!注意: 如果想要查出满足条件的总数 在sqlSERVER中可以用 COUNT(1) OVER() as TotalCount 以在分页查询时 也统计到所有总数
//不理解此句话就接着往下看文章
string sql = @"
Select S1.*, TotalCount
From(
select ROW_NUMBER() OVER(order by S.DocKey desc) as RowNum, COUNT(1) OVER() as TotalCount, S.*
from
(
" + innerSql + @"
) S
) S1
where S1.RowNum >= @start And S1.RowNum <= @end
";
SqlCommand command = new SqlCommand();
command.CommandText = sql;
command.Parameters.AddWithValue("@start", storeParams.start + 1);
command.Parameters.AddWithValue("@end", storeParams.start + storeParams.limit);
foreach(SqlParameter pa in parameters)
{
command.Parameters.Add(pa);
}
dt = ConnectionManager.ExecuteDataTable(command);
StoreResult result = new StoreResult();
result.root = dt;
if (dt != null && dt.Rows.Count > 0)
result.total = TypeHelper.GetIntValue(dt.Rows[0]["TotalCount"]);//将实际行数返回 不需要实际行数 就可以用下面 的Int32.MaxValue;
else result.total = 0;
//若是无需知道总数 可以用 result.total = Int32.MaxValue;
//一般前端用的list或dataview控件 就不关心实际总数 返回result.total 值 只是用于在前端可以展示 分页
return result;
}
一个是返回结果的类
namespace 命名空间
{
[Serializable]
public class StoreResult
{
public int total;
public object root;
public object footer;
}
}
另一个是store参数的类
namespace 命名空间
{
[Serializable]
public class StoreParams
{
public int page;
public int start;
public int limit;
public string query; //自动完成参数
public List group;
public List sort;
public List filter;
}
[Serializable]
public class StoreGrouper
{
public string property;
public string direction;
}
[Serializable]
public class StoreSorter
{
public string property;
public string direction;
}
[Serializable]
public class StoreFilter
{
public string property;
private string op;
[JsonProperty("operator")]
public string Operator
{
get
{
return op;
}
set
{
if (string.IsNullOrEmpty(value))
{
if (value == "!=") op = "<>";
else op = value;
}
else
{
throw WarningException.Parse("过滤器操作符{0}不合法", value);
}
}
}
public string value;
}
}
其他情况:
list使用的分页加载是不关心store的总数的,仅仅是为了出现“加载更多”字样
那后端在做分页查询处理时,若是无需查出真实总数,可以用
StoreResult result = new StoreResult();
result.total = Int32.MaxValue;// 直接用个最大常量 即可
如果这时还是直接返回Int32.MaxValue的话,grid的分页就会出现如下情况:
这时,应该在查询分页数时,就将总条数一并查出,使用
COUNT(1) OVER () as TotalCount
Select S1.*,TotalCount
From (
select ROW_NUMBER() OVER (order by S.DocKey desc) as RowNum,COUNT(1) OVER () as TotalCount, S.*
from
(
" + innerSql + @"
) S
) S1
where S1.RowNum >= @start And S1.RowNum <= @end
再返回前端总数值时 把查到的TotalCount 返回即可