ASP.NET:如何从javascript访问repeater生成的元素?

ASP.NET:如何从javascript访问repeater生成的元素?,asp.net,ajax,Asp.net,Ajax,我有一系列使用asp:repeater生成的行: <asp:repeater ID="itemsRepeater" OnItemDataBound="itemsRepeater_ItemDataBound" runat="Server"> <itemtemplate> <tr> <td> <asp:HyperLink ID="linkView" runat

我有一系列使用asp:repeater生成的行:

<asp:repeater ID="itemsRepeater" 
      OnItemDataBound="itemsRepeater_ItemDataBound" 
      runat="Server">
   <itemtemplate>
      <tr>
         <td>
            <asp:HyperLink ID="linkView" runat="server"
               Text="<%# GetItemText((Item)Container.DataItem) %>" 
               NavigateUrl="<%# GetViewItemUrl((Item)Container.DataItem) %>" />
         </td>
         <td>
            <asp:HyperLink ID="linkDelete" runat="server"
                Text="Delete"
                NavigateUrl="<%# GetDeleteUrl((ActionItem)Container.DataItem) %>" />
         </td>
      </tr>
   </itemtemplate>
</asp:repeater>
它是有效的——就像“要做的事——解决这个问题”一样有效


防止回发

上面模拟的javascript调用实际上发生了(我可以看到我的警报),但还有一个问题:javascript函数返回false不会阻止回发。事实上,我可以看到生成的html代码上的href不是“#”,而是

javascript:__doPostBack('ctl0....
我尝试更改ASPX代码以包含OnClick处理程序:

   OnClick="#"
   OnClientClick="DeleteItem('todo - figure this out');"
但编译人员认为英镑的一面是一个pragma,并抱怨道:

预处理器指令必须显示为 上的第一个非空白字符 一行


表行标识

表行没有ID,它们是由asp:repeater生成的

javascript函数如何知道是什么触发了单击事件?javascript需要能够找到元素,并将其从树中删除

注意:我当然更喜欢淡入淡出+折叠动画

通常通过使用

var tr = document.getElementById("the table row's id");
但是表行没有容易知道的ID。因为有多行,服务器在构建表时会生成ID。我意识到一些解决方案必须包括改变:

<TR>
但问题就在别处:如何为调用javascript函数填充tableRowElement和deleteUrl


这样一个简单的问题:将点击从回发转换为客户端

所涉及的问题数量变得相当愚蠢。这似乎表明

  • 想法解决方案是完全不同的
  • 没有解决办法

工具书类

可以为您找出标签:

$("[id$=linkDelete]").click(function() {
    DeleteItem(this.href);
});

该代码表示“找到ID以'linkDelete'结尾的所有DOM元素,并连接以下click事件处理程序”

我建议不要以这种方式通过链接实现删除功能

相反,最好是要求向该url发送帖子。如果您想使用ajax,我强烈建议您使用javascript框架,这样您就不必处理不同浏览器如何实现XmlHttpRequests的差异

例如,在jQuery中,您可以这样做:

$.post('Delete.aspx',{itemGuid:'{19a149db-5675-4eee-835d-3d78372ca6f9}'},
    function(data, textStatus) {
        if (textStatus == 'success') {
            $(this).parents('tr:eq(0)').fadeOut();
        }
    });
这将实现ajax调用和您想要的淡出效果

然后,您可以从Request.Form[“itemGuid”]访问Delete.aspx中的项目guid,这样就不会受到链接攻击

防止回发

服务器正在生成回发连线,因为您正在使用服务器控件。使用不带runat='server'指令的普通
标记

表行标识

我通常通过对某种ID列进行数据绑定并将其放入repeater模板来实现这一点:

<tr id='<%#Eval("ID")%>'>

另外,我不想听起来像个粉丝,但jQuery将使所有这些事情变得简单一个数量级。如果可以的话,你真的应该考虑一下。否则,在浏览器间以一致的方式实现这些特性会让您受到伤害


p.p.S.如果Delete.aspx和类似的URL只从javascript调用,我建议改用ashx http处理程序。您可以执行所有相同的服务器逻辑,而无需一个完整页面的不必要开销。

我的页面通常看起来像

<asp:LinkButton runat="server" OnClientClick='<%# Eval("ID", "DeleteItem(this, \"{0}\"); return false;") %>' Text="Delete" />

这将使html看起来像

<a id="blah_blah_ctl01" onclick='DeleteItem(this, "{19a149db-5675-4eee-835d-3d78372ca6f9}"); return false;'>Delete</a>
删除

我包含了“this”引用,这样您就可以访问dom并删除链接……或者它的父级或任何内容。从这里开始,使用jQuery实际执行发布和DOM操作就相当简单了。“return false;”禁用回发。

其他回答者发现了与问题不同方面相关的各种位。我设法拼凑出一个完整的解决办法。我已经在这里复制/粘贴了相关的剪贴画

第一个重要的变化是使用了一个asp:LinkButton,它允许asOnClientClick事件,您可以直接访问javascriptOnClick事件:

<asp:repeater ID="itemsRepeater"
      OnItemDataBound="itemsRepeater_ItemDataBound"
      runat="Server">
   <itemtemplate>
      <tr>         
         <td>
            <asp:HyperLink ID="linkView" runat="server"
               Text="<%# GetItemText((Item)Container.DataItem) %>"
               NavigateUrl="<%# GetViewItemUrl((Item)Container.DataItem) %>" />
         </td>
         <td>
            <asp:LinkButton ID="linkImpregnate" runat="server"
                   Text="Impregnate"
                   OnClientClick="<%# GetImpregnateUrl((Item)Container.DataItem) %>" />
         </td>
      </tr>
   </itemtemplate>
</asp:repeater>
最后,在aspx中,我找到了一个随机点,可以混入一些javascript:

<script type="text/javascript" src="Javascript/jquery.js"></script>  
<script type="text/javascript">
   //<![CDATA[
   function DeleteItem(sender, girlGuid, girlName)   
   {
      if (!confirm("Are you sure you want to impregnate "+girlName+"?"))
      {
         return false;
      }

      $.post(
         'ImpregnateGirl.aspx?GirlGUID='+nodeGuid,
               function(data, textStatus) {
                  if (textStatus == 'success') 
                  {
                     $(sender).parents('tr:eq(0)').hide();
                  }
                  else
                  {
                     return false;
                  }
               }
      );

      //return false to suppress the postback
      return false;
   }
//]]>
</script>

//

正如guy所建议的那样,作为一种安全措施,我会让jQuery做一个post,但是jQuery会给出一个错误,而不是post。不在乎,我选择了不在乎。

六个小时的无所事事,我可以花一个小时写一个问题。你愿意使用jQuery吗?这取决于它是否免费,除了程序集dll到bin文件夹之外不需要任何设置。它是免费的,除了程序集ddl之外不需要任何设置。这是一个很好的资源,它将为你打开许多你以前可能没有想到的酷功能的大门;否则,我只是在浪费时间玩一些没有实际应用的东西。你能进一步说明这个答案吗?这段代码去哪里,怎么去,以及“this.href”包含什么?我注意到代码中包含一个Guid,您能指出这段代码是如何生成的,它去哪里,以及它是如何到达那里的吗?我只是从您的代码中将其作为id字段的示例。据我所知,目前无法在jQuery中生成guid。$.post的第二个字段是要发布到服务器的表单变量的名称-值对的集合。
<TR runat="server">
function DeleteItem(tableRowElement, deleteUrl)
{
   //Do a web-hit of deleteUrl to delete the item


   //remove tableRowElement DOM object from the document tree
}
$("[id$=linkDelete]").click(function() {
    DeleteItem(this.href);
});
$.post('Delete.aspx',{itemGuid:'{19a149db-5675-4eee-835d-3d78372ca6f9}'},
    function(data, textStatus) {
        if (textStatus == 'success') {
            $(this).parents('tr:eq(0)').fadeOut();
        }
    });
<tr id='<%#Eval("ID")%>'>
<asp:LinkButton runat="server" OnClientClick='<%# Eval("ID", "DeleteItem(this, \"{0}\"); return false;") %>' Text="Delete" />
<a id="blah_blah_ctl01" onclick='DeleteItem(this, "{19a149db-5675-4eee-835d-3d78372ca6f9}"); return false;'>Delete</a>
<asp:repeater ID="itemsRepeater"
      OnItemDataBound="itemsRepeater_ItemDataBound"
      runat="Server">
   <itemtemplate>
      <tr>         
         <td>
            <asp:HyperLink ID="linkView" runat="server"
               Text="<%# GetItemText((Item)Container.DataItem) %>"
               NavigateUrl="<%# GetViewItemUrl((Item)Container.DataItem) %>" />
         </td>
         <td>
            <asp:LinkButton ID="linkImpregnate" runat="server"
                   Text="Impregnate"
                   OnClientClick="<%# GetImpregnateUrl((Item)Container.DataItem) %>" />
         </td>
      </tr>
   </itemtemplate>
</asp:repeater>
protected string GetNodeAcknowledgementClientClick(Item item)
{
   if (!(item is HotGirl))
      return ""; //this shouldn't be called for non-acknowledgements, but i won't fail

   HotGirl girl = (HotGirl)item;

   String szOnClientClick =
         "return ImpregnateGirl(this, "+
               Toolkit.QuotedStr(girl.GirlGUID.ToString()) + ", "+
               Toolkit.QuotedStr(GetItemName(item))+");";

   return szOnClientClick;
}
<script type="text/javascript" src="Javascript/jquery.js"></script>  
<script type="text/javascript">
   //<![CDATA[
   function DeleteItem(sender, girlGuid, girlName)   
   {
      if (!confirm("Are you sure you want to impregnate "+girlName+"?"))
      {
         return false;
      }

      $.post(
         'ImpregnateGirl.aspx?GirlGUID='+nodeGuid,
               function(data, textStatus) {
                  if (textStatus == 'success') 
                  {
                     $(sender).parents('tr:eq(0)').hide();
                  }
                  else
                  {
                     return false;
                  }
               }
      );

      //return false to suppress the postback
      return false;
   }
//]]>
</script>