0

我在我的页面中有一个<asp:CheckBoxList>using动态分配值。RepeatLayout="Flow"如果页面是第一次加载(!IsPostBack),呈现的版本看起来与此类似;

<span children="Cat">
    <input id="ctl00_Menu_Category_0" type="checkbox" name="ctl00$Menu$Category$0"/>
    <label for="ctl00_Menu_Category_0">Cat</label>
</span>
<br/>
<span class="Cat">
    <input id="ctl00_Menu_Category_1" type="checkbox" name="ctl00$Menu$Category$1"/>
    <label for="ctl00_Menu_Category_1"> - SubCat1</label>
</span>

children是我用于 jQuery 代码的属性,所以当用户检查时Cat,所有SubCat的 s 也会被检查。

jQuery 代码搜索所有<span>类等于children-attribute 的 s,因此我需要维护 jQuery 工作的这个结构。

但是,在我重新加载页面或点击链接之后,无论如何,列表突然看起来像这样:

<input id="ctl00_Menu_Category_0" type="checkbox" name="ctl00$Menu$Category$0"/>
<label for="ctl00_Menu_Category_0">Cat</label>
<br/>
<input id="ctl00_Menu_Category_1" type="checkbox" name="ctl00$Menu$Category$1"/>
<label for="ctl00_Menu_Category_1"> - SubCat1</label>

这怎么可能呢?我只将值分配给列表一次,那么为什么在 PostBack 之后重新渲染它,我该如何防止它这样做呢?

编辑

这是创建列表的代码;

// Get all available categories that are not a child of another category
DataTable categoryParents = functions.SelectSql(Resources.Data.GetCategoryParents);

// Get the child categories
foreach (DataRow parent in categoryParents.Rows)
{
    // Add the category
    ListItem parentItem = new ListItem(parent["Name"].ToString(), parent["Name"].ToString());
    parentItem.Attributes.Add("children", parent["Name"].ToString().Replace(' ', '_'));
    Category.Items.Add(parentItem);

    // For every parent category, get all its child categories
    DataTable categoryChildren = functions.SelectSql(Resources.Data.GetCategoryChildrenByParent.Replace("##PARENTID##", parent["ID"].ToString()));

    // Add the child categories after their parents
    foreach (DataRow child in categoryChildren.Rows)
    {
        ListItem item = new ListItem(" - " + child["Name"].ToString(), parent["Name"].ToString() + "\\" + child["Name"].ToString());
        item.Attributes.Add("class", parent["Name"].ToString().Replace(' ', '_'));
        Category.Items.Add(item);
    }
}
Category.DataBind();

jQuery 本身不对 HTML 做任何事情,它只是拥有在检查父项时检查子类别的功能;

$("#Category :checkbox").click(function(){
    var checked = $(this).attr("checked");
    var children = $(this).parent("span").attr("children");
    $("#Category ." + children + " :checkbox").attr("checked", checked);
});
4

1 回答 1

0

每次重新加载页面时都会呈现整个 HTML 代码。您可以通过检查来防止IsPostBack更改这次HTML 的呈现方式。这意味着当页面回发时,服务器不会将复选框列表与新值绑定,而是会直接使用存储在 ViewState 中的值以与上次完全相同的方式呈现它们。

如果您的 jQuery 代码在呈现后更改了 HTML,服务器将不知道并且实际上没有可行的方法来更改它。这里有趣的问题是:包装跨度和children属性以及所有代码首先是如何应用的?

您的选择是执行以下操作之一:

  • 发出 AJAX 请求而不是完整的回发,只更改您想要更改的 DOM 部分
  • 在回发后的 DOMReady 上重新应用实现此更改的 jQuery 代码

编辑

针对原始帖子中的编辑:

Category你的CheckBoxList吗?如果您已经迭代地将所有列表项添加到其中,那之后为什么还要重新绑定它呢?我认为第一个 for 循环应该使数据绑定过时。

我最好的猜测是,当CheckBoxList被序列化为 ViewState 时,它​​会存储应用于它的属性,以及列表项的 id/value 字典(而不是您迭代应用的其他属性)。

如果它没有保存在 ViewState 中 - 看起来它不是 - 没有真正干净的解决方案可以解决您的问题。解决方法是在每次页面加载时执行代码,或者CheckBoxList在覆盖该Render方法的子类中继承代码,以始终生成您想要的输出。事实上,如果您在整个站点中大量使用它,最后一个选项可能非常简洁......?

于 2009-12-10T10:54:17.277 回答