我已经创建了一个伪网格窗口小部件(基本上只是一个网格头),允许用户根据自己的喜好配置排序和过滤器,然后保存这些配置以供将来使用。问题是它们是作为字符串从数据库返回的。不幸的是,我需要一种将它们转换回javascript对象的方法,以便将它们应用到网格中。
我正在使用下面的parameterMap函数将DataSourceRequest对象转换为可以发布到控制器操作并保存在数据库中的对象。该函数只接受从kendoGrid.dataSource
返回的对象,并将它们转换为各种查询字符串。所以,这个:
// Get datasource of the filter grid, so we can save the search applied to it.
var f = $("#filter-grid").data("kendoGrid").dataSource;
// Set the filtering/sorting applied to the filter grid in the model being saved.
e.model.Request = e.sender.dataSource.transport.parameterMap({
filter: f.filter(),
group: f.group(),
page: f.page(),
pageSize: f.pageSize(),
sort: f.sort()
});
返回:
Object {
sort: "InvoiceNumber-asc",
page: 1,
pageSize: 100,
group: "",
filter: "Auditor~startswith~'Gabe'~and~Auditor~endswith~'Newell'"
}
是否有任何javascript函数提供Kendo UI的东西,允许将查询字符串解析为javascript对象?我基本上想要反转parameterMap()
函数的结果。我的最终目标是避免将我自己的解析这些字符串的方法转换回对象,而且似乎Kendo套件中的某些东西应该为我处理这个问题。
Telerik文档确实提供了一种方法来执行我正在寻找的内容(GridCommand.Parse()),但是在控制器中可以使用它,我需要在页面上完成此操作。如果我能找到类似于基于jQuery的框架中提供的MVC扩展的东西,那么这实现起来要容易得多。
提前致谢。
答案 0 :(得分:3)
在Telerik论坛上询问后,显然在Telerik jQuery框架中没有提供这样做的方法。所以,我继续并实施了一个。
如果有人好奇的话,这是jsfiddle的链接。它只支持过滤字符串和排序字符串,因为我还没有用于解析组字符串。
过滤字符串:
function parseFilterString(filterString) {
// sample filter: "(Auditor~startswith~'Gabe'~and~Auditor~endswith~'Newell')~and~(Company~contains~'Valve'~and~Company~neq~'EA')";
// Remove all of the ' characters from the string.
filterString = filterString.replace(/[']/g, '');
// Split the string into an array of strings, using the ~ as a delimiter.
var ss = filterString.split("~"); // ss stands for "split string". I'm clever.
var F = []; // Used to store all of the parsed filters.
var fIndex = -1; // Used to track filter index.
var cIndex = 0; // Used to track filter index within a composite filter object.
var isComposite = false; // Used to indicate if a composite filter is currently being parsed.
for (var i = 0; i < ss.length; i++) {
if (i % 4 == 0) { // Field.
if (ss[i].indexOf('(') > -1) { // If we're starting a composite object, create a composite object and add it to the parsed filters.
F.push({
filters: [],
logic: ""
});
fIndex++; // We added an object to the array, so increment the counter.
F[fIndex]
F[fIndex].filters.push({
field: ss[i].replace('(', ''),
operator: "",
value: ""
});
cIndex = 0; // We added the first filter to the composite object, so set the counter.
isComposite = true;
}
else if (isComposite) { // If we're parsing the second filter in a composite filter object, then add the field to the child filter.
F[fIndex].filters.push({
field: ss[i],
operator: "",
value: ""
});
cIndex++; // We added the second filter to the composite object, so increment the counter.
}
else { // Add the field as normal.
F.push({
field: ss[i],
operator: "",
value: ""
});
fIndex++; // We added an object to the array, so increment the counter.
}
}
if (i % 4 == 1) { // Operator.
if (isComposite) {
F[fIndex].filters[cIndex].operator = ss[i];
}
else {
F[fIndex].operator = ss[i];
}
}
if (i % 4 == 2) { // Value.
if (ss[i].indexOf(')') > -1) {
F[fIndex].filters[cIndex].value = ss[i].replace(')', '');
isComposite = false;
}
else if (isComposite) {
F[fIndex].filters[cIndex].value = ss[i];
}
else {
F[fIndex].value = ss[i];
}
}
if (i % 4 == 3) { // Logic.
if (isComposite) {
F[fIndex].logic = ss[i]; // Add the logic to the composite filter object.
}
// If the filter is not composite, the logic will always be "and". So, we just don't do anything if that's the case.
}
}
return {
filters: F,
logic: "and"
};
};
排序字符串:
function parseSortString(sortString) {
// sample multi-level sort: "Auditor-asc~Company-desc~Invoice-asc";
// Split the string into an array of strings, using the ~ as a delimiter.
var ss = sortString.split("~"); // ss stands for "split string". I'm clever.
var S = []; // Array containing sort objects.
for (var i = 0; i < ss.length; i++) {
var sort = ss[i].split('-'); // Split sort string into field and direction.
S.push({
compare: undefined, // This field exists in the sort objects, but is always undefined (as far as I can tell). I added it anyways, to minimize potential future issues.
dir: sort[1], // Direction.
field: sort[0] // Field.
});
}
return S;
};
答案 1 :(得分:0)
var filter =“(审计员以“ Gabe”开始,审计员以“ Newell”结束),并且(公司包含“阀门”和“ neq〜'EA'”);
if (filter == "") {
return {};
}
if (filter.indexOf("(") == -1) {
filter = "(" + filter + ")";
}
var pattern = /(\()([^\(\)]+)(\))/g;
//var pattern = /(.*)/g;
var filterSub = { logic: null, filters: [] };
var filterObject = {};
function parser() {
var matchParam = filter.match(pattern);
if (matchParam != null) {
matchParam.forEach(function (e) {
var item = e.split('(').join('').split(')').join('');
var logic = item.indexOf("~or~") > -1 ? "or" : "and";
var items = item.indexOf("~or~") > -1 ? item.split('~or~') : item.split('~and~');
filterSub = { logic: null, filters: [] };
items.forEach(function (c, i) {
var obj = filterObject[c];
if (obj == null) {
var cArr = c.split("~");
obj = {
field: cArr[0],
operator: cArr[1],
value: (cArr[2] || "").split("'").join("")
};
}
if (items.length == 1) {
filterSub = obj;
} else if (items.length >= 2) {
if (filterSub.filters.length == 2) {
filterSub = {
logic: logic,
filters: [obj, filterSub]
}
} else {
filterSub.logic = logic;
filterSub.filters.push(obj);
}
}
});
var length = Object.keys(filterObject).length;
var name = "####" + length;
filterObject[name] = filterSub;
filter = filter.replace(e, name);
});
if (matchParam.length > 0) {
parser();
}
}
};
parser();
return filterSub;