我可以停止.NET进食ID吗?

时间:2020-03-05 18:46:18  来源:igfitidea点击:

如今,我是一名信息架构师和JavaScript开发人员,但是最近我又重新回到了后端编码中。而且,在尝试集成HTML原型并与我们基于C#的CMS一起工作的同时,我对程序员感到震惊,因为.NET为表单元素随意重写了HTML ID属性。

我可以理解.NET更改ID的背后代码推理,但事实是,在尝试开发例如.NET时不再可以使用ID。 jQuery增强接口引起一些摩擦。我该怎么办才能解决此问题?

我尝试使用class属性来代替,但这确实很糟糕,不是它的含义,并且也无法解决.NET有效地动态更改渲染源的问题。这也意味着CSS现在不再有用,并且创建和维护的效率也更低。

任何提示或者建议都将不胜感激-减少不眠之夜的任何事情...

解决方案

回答

我们可以扩展.net控件,并在调用相关属性时使它们返回实际的ID。

ClientID是id属性,而UniqueID是html元素的名称属性。因此,当我们创建如下所示的文本框并使用它代替框架中的文本框时,将使id和name属性呈现为与服务器端ID相同。

public class MyTextBox : TextBox
{
    public override string ClientID { get { return ID; } }
    public override string UniqueID { get { return ID; } }
}

要使用此新用户控件,请像注册自定义用户控件一样,基本上注册该控件(我们可以在web.config中进行操作,因此不必在所有页面中都使用它):

<%@ Register Assembly="MyLibrary" NameSpace="MyLibrary.WebControls" TagPrefix="MyPrefix" %>

像使用文本框一样使用它:

<MyPrefix:MyTextBox ID="sampleTextBox" runat="server" />

回答

简短的回答是"否",对于webforms,始终可以根据元素的嵌套来重写id。我们可以通过ClientID属性访问ID,因此可以在页面/控件末尾的脚本中将ID设置为变量,然后将其放入jQuery。

像这样的东西:

<asp:button id="ImAButton" runat="server">Click Me</asp:button>

<script type="text/javascript">
var buttonId = "<%=ImAButton.ClientId%>";
$("#"+buttonId).bind('click', function() { alert('hi); });
</script>

我知道这是一种hack,但可以使用。

回答

(对于未启动的用户,我应该注意,我在这里使用Prototype $ get by id方法)

public override string UniqueID
{
  get { return this.ID; }
}
public override string ClientID
{
  get { return this.ID; }
}

一种方法是手动覆盖ID:

回答

里克·斯特拉尔(Rick Strahl)写了一篇博客文章,其中包含有关该方法的更多信息。

查看ASP.Net MVC,它解决了ASP.Net默认情况下生成的过度杀害对象层次结构。

这个站点是用MVC编写的(我认为)是看它的结构。我现在正在研究一个新项目吗?

如果我们坚持使用基本的ASP.Net,请小心覆盖ClientID和UniqueID,它往往会破坏许多Web控件。

回答

我发现最好的方法是将不可读的ClientID传递给Javascript。

public void RegisterControlClientID(Control control)
{
   string variableDeclaration = string.Format("var {0} = \"{1}\";", control.ID, control.ClientID);
   ClientScript.RegisterClientScriptBlock(GetType(), control.ID, variableDeclaration, true);
}

就个人而言,我使用了一些方法来桥接服务器端ASP.NET"魔术"(我尚未使用MS MVC的东西)和客户端代码,这是因为发生的ID变大了。这只是一个可能有用或者可能不有用的选项:

RegisterControlClientID(m_SomeTextBox);

因此,在服务器端代码中,我们只需调用此方法并传递要为其使用更友好名称的控件的实例。换句话说,在设计期间,我们可能会有一个ID为" m_SomeTextBox"的文本框,并且希望能够使用相同的名称来编写JavaScript,而我们只需在服务器端代码中调用此方法即可:

var m_SomeTextBox = "ctl00_m_ContentPlaceHolder_m_SomeTextBox";

然后在客户端上呈现以下内容:

回答

这样,所有JavaScript代码都可能完全不了解ASP.NET决定命名变量的方式。确实,对此有一些警告,例如,当我们在页面上有多个控件实例时(例如,由于使用了多个用户控件实例,其中都包含一个m_SomeTextBox实例),但是通常此方法可以满足最基本需求。

var elemPrefix = 'ctl00-ContentPlaceHolder-'; //replace the dashes for underscores

var o = function(name)
{    
    return document.getElementById(elemPrefix + name)
}

我通常要做的是创建一个接收字段名称的通用函数。它添加通常的" asp.net"前缀并返回对象。

$(o('buttonId')).bind('click', function() { alert('hi); });

回答

这样,我们就可以在jQuery中使用这种调用

$('fieldset > input[type="submit"]').click(function() {...});

回答

如果我们使用的是jQuery,则可以使用大量CSS选择器和jQuery custome选择器来定位页面上的目标元素。因此,与其通过id来选择一个提交按钮,我们还可以执行以下操作:

我们绝对不希望将asp.net生成的ID硬编码到CSS中,因为如果以控制树更改的方式重新排列页面上的内容,它可能会更改。

我们说对了,CSS ID占了上风,所以我将忽略仅使用类的建议。

这里描述的各种JavaScript hack都是一个小问题的矫kill过正。从类继承并覆盖ID属性也是如此。当我们只想重构一些CSS时,建议切换到MVC肯定没有帮助。

<div id="DataGridContainer">
     <asp:datagrid runat=server id="DataGrid" >
         ......
     <asp:datagrid>
  </div>

回答

只需使用CSS定位单独的div和span。如果要使用ID,请不要直接定位ASP.NET控件。

<asp:button id="ImAButton" runat="server">Click Me</asp:button>

<script type="text/javascript">
var buttonId = <%=ImAButton.ClientId%>
$(buttonId).bind('click', function() { alert('hi); });
</script>

我可以看到.NET系统感觉不太直观,但是给了机会。以我的经验,它实际上最终会创建更简洁的代码。当然

<script type="text/javascript">
function MakeAClick(inid)
{
  $(inid).bind('click', function() { alert('hi); });
}
</script>

工作正常。但这是没有模块化的困扰。我们真正想要的是这样的东西:

然后在Java端或者C端添加代码,然后调用MakeAClick。当然,在Cside上更有意义,我们只需在其中找到ClientID。

段落数量不匹配