查询字符串参数
Query String Parameters
想法:
只有两列的自定义网格视图。我没有传统的具有多列值的网格视图,而是有两列,列内有多个值。下面是 link 屏幕,显示结果很好。
既然网格视图可以正常工作,并且它的值会在页面加载时按应有的方式填充,我将合并与网格视图关联的传统功能。例如;搜索、过滤、排序和分页。这些是我希望我的网格视图具有的四个主要功能。
问题:
到目前为止一切顺利,搜索、筛选、排序和分页都可以正常工作;但是,它们都有一个共同的问题:我无法组合这些功能。我希望能够,但是在将查询字符串添加到项目中并完全重构我的代码后,每个功能只能工作一次。
例如:如果我选择按新筛选,然后按创建日期排序,我会单击 'New',然后单击 'Date Created'。当我单击 'New' 时,查询字符串看起来像 'view=new&sort=customer&dir=ASC&page=1'。这是预料之中的,但是当我单击 'Date Created' 时出现了意想不到的结果;查询字符串更改为 'view=all&sort=creaon&dir=ASC&page=1'。视图在不应该的时候发生了变化。
这个事实对所有测试用例都是一样的。隐藏字段正在接收值,但由于它们的值是在单击事件上分配的,因此不会在 post 中保留它们的值。过去我没有遇到隐藏字段执行此操作的任何问题,所以我想知道我现在做错了什么,我在看什么?另外,如果这不是解决此问题的正确方法,那会是什么?
代码
目前我所能提供的就是这个特定问题的相关代码;搜索值由 Session 处理,其余值由隐藏字段处理。
分页元素是在后台代码中的页面加载时创建的。
JavaScript:
function setView(id, mode) {
document.getElementById('PlaceHolderMainLower_PackageView_hfViewMode').setAttribute('Value', mode);
setHref(id);
}
function setSort(id, mode) {
document.getElementById('PlaceHolderMainLower_PackageView_hfSortMode').setAttribute('Value', mode);
setHref(id);
}
function setPage(id, page) {
document.getElementById('PlaceHolderMainLower_PackageView_hfPageIndex').setAttribute('Value', page);
setHref(id);
}
function setHref(id) {
var view = document.getElementById('PlaceHolderMainLower_PackageView_hfViewMode').value;
var sort = document.getElementById('PlaceHolderMainLower_PackageView_hfSortMode').value;
var dir = document.getElementById('PlaceHolderMainLower_PackageView_hfSortDirection').value;
var page = document.getElementById('PlaceHolderMainLower_PackageView_hfPageIndex').value;
document.getElementById(id).href = 'ActivePackages.aspx?' + 'view=' + view + '&sort=' + sort + '&dir=' + dir + '&page=' + page;
__doPostBack();
}
CSS:
.viewLinks {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.viewLinks:hover {
cursor: pointer;
}
HTML:
<asp:ScriptManager ID="scriptManager" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="upHiddenFields" runat="server" UpdateMode="Always" EnableViewState="true" ViewStateMode="Enabled" >
<ContentTemplate>
<asp:HiddenField ID="hfViewMode" runat="server" Value="all" EnableViewState="true" ViewStateMode="Enabled" />
<asp:HiddenField ID="hfSortMode" runat="server" Value="customer" EnableViewState="true" ViewStateMode="Enabled" />
<asp:HiddenField ID="hfSortDirection" runat="server" Value="ASC" EnableViewState="true" ViewStateMode="Enabled" />
<asp:HiddenField ID="hfPageIndex" runat="server" Value="1" EnableViewState="true" ViewStateMode="Enabled" />
</ContentTemplate>
</asp:UpdatePanel>
<div id="divViews" style="display: table; width: 100%; table-layout: fixed;">
<span>View By Status:</span>
<asp:LinkButton ID="lnkAll" runat="server" CssClass="viewLinks" Text="All" OnClientClick="setView(this.id, 'all');" />
<asp:LinkButton ID="lnkNew" runat="server" CssClass="viewLinks" Text="New" OnClientClick="setView(this.id, 'new');" />
<asp:LinkButton ID="lnkProgress" runat="server" CssClass="viewLinks" Text="In Progress" OnClientClick="setView(this.id, 'inProgress');" />
</div>
<div id="divViews" style="display: table; width: 100%; table-layout: fixed;">
<span>Sort By:</span>
<asp:LinkButton ID="lnkCustomer" runat="server" CssClass="viewLinks" Text="Customer" OnClientClick="setSort(this.id, 'customer');" />
<asp:LinkButton ID="lnkType" runat="server" CssClass="viewLinks" Text="Type" OnClientClick="setSort(this.id, 'type');" />
<asp:LinkButton ID="lnkCreatedOn" runat="server" CssClass="viewLinks" Text="Date Created" OnClientClick="setSort(this.id, 'creaon');" />
</div>
C#:
private const string pageLinkTemplateHTML = @"<a id=""pageLink{0}"" onclick=""setPage(this.id, {1});"" class=""viewLinks"">{2}</a>";
private void BuildPaging() {
divPages.InnerHtml = @"<table style=""width: 100%;""><tr><td style=""width: 100%"">";
for (int i = 1; i <= Packages.Count / pageSize; i++)
divPages.InnerHtml += string.Format(pageLinkTemplateHTML, i, i, i);
divPages.InnerHtml += "</td></tr></table>";
}
正如我在评论中所说,您可以使用变量来存储您的选择状态。示例:
// do the same for your other variables
var view = 'all';
function setView(id, mode) {
view = mode;
setHref(id);
}
function setHref(id) {
// now you don't need to read view, sort,
// dir and page from DOM elements, they are already there
document.getElementById(id).href = 'ActivePackages.aspx?' + 'view=' + view + '&sort=' + sort + '&dir=' + dir + '&page=' + page;
__doPostBack();
}
// on page load, you read the querystring from the url, check for the values and put them back into variables
window.addEventListener('load', function(){
var query_string = {};
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
// If first entry with this name
if (typeof query_string[pair[0]] === "undefined") {
query_string[pair[0]] = decodeURIComponent(pair[1]);
// If second entry with this name
} else if (typeof query_string[pair[0]] === "string") {
query_string[pair[0]] = [query_string[pair[0]],decodeURIComponent(pair[1])];
// If third or later entry with this name
} else {
query_string[pair[0]].push(decodeURIComponent(pair[1]));
}
}
// do the same for your other parameters
if(query_string.hasOwnProperty('view')){
view = query_string.view;
}
});
想法:
只有两列的自定义网格视图。我没有传统的具有多列值的网格视图,而是有两列,列内有多个值。下面是 link 屏幕,显示结果很好。
既然网格视图可以正常工作,并且它的值会在页面加载时按应有的方式填充,我将合并与网格视图关联的传统功能。例如;搜索、过滤、排序和分页。这些是我希望我的网格视图具有的四个主要功能。
问题:
到目前为止一切顺利,搜索、筛选、排序和分页都可以正常工作;但是,它们都有一个共同的问题:我无法组合这些功能。我希望能够,但是在将查询字符串添加到项目中并完全重构我的代码后,每个功能只能工作一次。
例如:如果我选择按新筛选,然后按创建日期排序,我会单击 'New',然后单击 'Date Created'。当我单击 'New' 时,查询字符串看起来像 'view=new&sort=customer&dir=ASC&page=1'。这是预料之中的,但是当我单击 'Date Created' 时出现了意想不到的结果;查询字符串更改为 'view=all&sort=creaon&dir=ASC&page=1'。视图在不应该的时候发生了变化。
这个事实对所有测试用例都是一样的。隐藏字段正在接收值,但由于它们的值是在单击事件上分配的,因此不会在 post 中保留它们的值。过去我没有遇到隐藏字段执行此操作的任何问题,所以我想知道我现在做错了什么,我在看什么?另外,如果这不是解决此问题的正确方法,那会是什么?
代码
目前我所能提供的就是这个特定问题的相关代码;搜索值由 Session 处理,其余值由隐藏字段处理。
分页元素是在后台代码中的页面加载时创建的。
JavaScript:
function setView(id, mode) {
document.getElementById('PlaceHolderMainLower_PackageView_hfViewMode').setAttribute('Value', mode);
setHref(id);
}
function setSort(id, mode) {
document.getElementById('PlaceHolderMainLower_PackageView_hfSortMode').setAttribute('Value', mode);
setHref(id);
}
function setPage(id, page) {
document.getElementById('PlaceHolderMainLower_PackageView_hfPageIndex').setAttribute('Value', page);
setHref(id);
}
function setHref(id) {
var view = document.getElementById('PlaceHolderMainLower_PackageView_hfViewMode').value;
var sort = document.getElementById('PlaceHolderMainLower_PackageView_hfSortMode').value;
var dir = document.getElementById('PlaceHolderMainLower_PackageView_hfSortDirection').value;
var page = document.getElementById('PlaceHolderMainLower_PackageView_hfPageIndex').value;
document.getElementById(id).href = 'ActivePackages.aspx?' + 'view=' + view + '&sort=' + sort + '&dir=' + dir + '&page=' + page;
__doPostBack();
}
CSS:
.viewLinks {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.viewLinks:hover {
cursor: pointer;
}
HTML:
<asp:ScriptManager ID="scriptManager" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="upHiddenFields" runat="server" UpdateMode="Always" EnableViewState="true" ViewStateMode="Enabled" >
<ContentTemplate>
<asp:HiddenField ID="hfViewMode" runat="server" Value="all" EnableViewState="true" ViewStateMode="Enabled" />
<asp:HiddenField ID="hfSortMode" runat="server" Value="customer" EnableViewState="true" ViewStateMode="Enabled" />
<asp:HiddenField ID="hfSortDirection" runat="server" Value="ASC" EnableViewState="true" ViewStateMode="Enabled" />
<asp:HiddenField ID="hfPageIndex" runat="server" Value="1" EnableViewState="true" ViewStateMode="Enabled" />
</ContentTemplate>
</asp:UpdatePanel>
<div id="divViews" style="display: table; width: 100%; table-layout: fixed;">
<span>View By Status:</span>
<asp:LinkButton ID="lnkAll" runat="server" CssClass="viewLinks" Text="All" OnClientClick="setView(this.id, 'all');" />
<asp:LinkButton ID="lnkNew" runat="server" CssClass="viewLinks" Text="New" OnClientClick="setView(this.id, 'new');" />
<asp:LinkButton ID="lnkProgress" runat="server" CssClass="viewLinks" Text="In Progress" OnClientClick="setView(this.id, 'inProgress');" />
</div>
<div id="divViews" style="display: table; width: 100%; table-layout: fixed;">
<span>Sort By:</span>
<asp:LinkButton ID="lnkCustomer" runat="server" CssClass="viewLinks" Text="Customer" OnClientClick="setSort(this.id, 'customer');" />
<asp:LinkButton ID="lnkType" runat="server" CssClass="viewLinks" Text="Type" OnClientClick="setSort(this.id, 'type');" />
<asp:LinkButton ID="lnkCreatedOn" runat="server" CssClass="viewLinks" Text="Date Created" OnClientClick="setSort(this.id, 'creaon');" />
</div>
C#:
private const string pageLinkTemplateHTML = @"<a id=""pageLink{0}"" onclick=""setPage(this.id, {1});"" class=""viewLinks"">{2}</a>";
private void BuildPaging() {
divPages.InnerHtml = @"<table style=""width: 100%;""><tr><td style=""width: 100%"">";
for (int i = 1; i <= Packages.Count / pageSize; i++)
divPages.InnerHtml += string.Format(pageLinkTemplateHTML, i, i, i);
divPages.InnerHtml += "</td></tr></table>";
}
正如我在评论中所说,您可以使用变量来存储您的选择状态。示例:
// do the same for your other variables
var view = 'all';
function setView(id, mode) {
view = mode;
setHref(id);
}
function setHref(id) {
// now you don't need to read view, sort,
// dir and page from DOM elements, they are already there
document.getElementById(id).href = 'ActivePackages.aspx?' + 'view=' + view + '&sort=' + sort + '&dir=' + dir + '&page=' + page;
__doPostBack();
}
// on page load, you read the querystring from the url, check for the values and put them back into variables
window.addEventListener('load', function(){
var query_string = {};
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
// If first entry with this name
if (typeof query_string[pair[0]] === "undefined") {
query_string[pair[0]] = decodeURIComponent(pair[1]);
// If second entry with this name
} else if (typeof query_string[pair[0]] === "string") {
query_string[pair[0]] = [query_string[pair[0]],decodeURIComponent(pair[1])];
// If third or later entry with this name
} else {
query_string[pair[0]].push(decodeURIComponent(pair[1]));
}
}
// do the same for your other parameters
if(query_string.hasOwnProperty('view')){
view = query_string.view;
}
});