Pergunta

Atualmente sou arquiteto de informações e desenvolvedor de JavaScript profissionalmente, mas recentemente voltei à codificação back-end.E, enquanto tentava integrar um protótipo HTML e trabalhar com nosso CMS baseado em C#, briguei com nossos programadores sobre os atributos de ID HTML sendo reescritos arbitrariamente pelo .NET para elementos de formulário.

Posso entender o raciocínio por trás do código para a alteração de IDs do .NET, mas o fato de você não poder mais usar IDs ao tentar desenvolver, por exemplo.As interfaces aprimoradas do jQuery estão causando algum atrito.O que posso fazer para contornar isso?

Em vez disso, tentei usar o atributo class, mas isso é realmente uma porcaria, não é o objetivo e não resolve o problema do .NET alterar efetivamente a fonte renderizada em tempo real.Isso também significa que o CSS é menos útil agora e menos eficiente para criar e manter.

Qualquer dica ou conselho será muito apreciado - qualquer coisa por algumas noites menos sem dormir...

Foi útil?

Solução

A resposta curta é não, com webforms o id sempre pode ser reescrito dependendo do aninhamento do elemento.Você pode obter acesso ao id através da propriedade ClientID, para poder definir os ids em variáveis ​​​​em um script no final da página/controle e colocá-los no jQuery.

algo assim:

<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>

É um truque, eu sei, mas vai funcionar.(Devo observar que para os não iniciados, estou usando o método Prototype $ get by id lá)

Outras dicas

Um método é substituir os IDs manualmente:

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

Rick Strahl escreveu uma postagem no blog com mais algumas informações sobre essa abordagem.

Veja o ASP.Net MVC - ele aborda as hierarquias de objetos exageradas que o ASP.Net gera por padrão.

Este site está escrito em MVC (eu acho) - veja sua estrutura.Se eu estivesse trabalhando em um novo projeto agora, consideraria isso primeiro

Se você estiver preso ao ASP.Net básico, tome cuidado ao substituir ClientID e UniqueID - isso tende a quebrar muitos controles da web.

A melhor maneira que encontrei é passar o ClientID ilegível para o Javascript.

Você pode estender os controles .net e fazê-los retornar IDs reais quando propriedades relacionadas são chamadas.

ClientID é o atributo id e UniqueID é o atributo name dos elementos html.Portanto, quando você cria uma caixa de texto como a seguinte e a usa em vez da caixa de texto na estrutura, você faz com que os atributos id e name sejam renderizados da mesma forma que o id do lado do servidor.

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

Para usar esse novo controle de usuário, basicamente registre esse controle como faria para um controle de usuário personalizado (você pode fazer isso em web.config para não precisar fazer isso em todas as suas páginas):

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

E use-o como usaria uma caixa de texto:

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

Pessoalmente, eu uso um conjunto de métodos que desenvolvi para fazer a ponte entre a "mágica" do ASP.NET do lado do servidor (ainda não usei o material do MS MVC) e meu código do lado do cliente por causa da manipulação dos IDs que acontece .Aqui está apenas um que pode ou não ser útil:

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

Portanto, em seu código do lado do servidor, você simplesmente chama isso e passa a instância de um controle para o qual deseja usar um nome mais amigável.Em outras palavras, durante tempo de projeto, você pode ter uma caixa de texto com o ID "m_SomeTextBox" e deseja escrever seu JavaScript usando esse mesmo nome - basta chamar esse método no código do lado do servidor:

RegisterControlClientID(m_SomeTextBox);

E então no cliente é renderizado o seguinte:

var m_SomeTextBox = "ctl00_m_ContentPlaceHolder_m_SomeTextBox";

Dessa forma, todo o seu código JavaScript pode ignorar o que o ASP.NET decide nomear a variável.É verdade que existem algumas ressalvas quanto a isso, como quando você tem várias instâncias de um controle em uma página (devido ao uso de várias instâncias de controles de usuário que possuem uma instância de m_SomeTextBox dentro deles, por exemplo), mas geralmente esse método pode ser útil para suas necessidades mais básicas.

O que costumo fazer é criar uma função geral que receba o nome do campo.Ele adiciona o prefixo "asp.net" usual e retorna o objeto.

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

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

Com isso você pode usar esse tipo de chamadas em jQuery

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

Definitivamente, você não deseja codificar o ID gerado pelo asp.net em seu CSS, porque ele pode mudar se você reorganizar as coisas em sua página de forma que sua árvore de controle mude.

Você está certo ao dizer que os IDs CSS têm seu lugar, então eu ignoraria as sugestões de usar apenas classes.

Os vários hacks de javascript descritos aqui são um exagero para um pequeno problema.O mesmo acontece com herdar de uma classe e substituir a propriedade ID.E certamente não é útil sugerir mudar para MVC quando tudo que você quer fazer é refatorar algum CSS.

Basta ter divs e spans separados que você segmenta com CSS.Não direcione os controles ASP.NET diretamente se quiser usar IDs.

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

Se você estiver usando jQuery, terá muitos Seletores CSS e seletores personalizados jQuery à sua disposição para direcionar os elementos da sua página.Então, em vez de escolher um botão de envio pelo seu ID, você poderia fazer algo como:

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

Posso ver como o sistema .NET parece menos intuitivo, mas dê uma chance.Na minha experiência, isso acaba criando um código mais limpo.Claro

<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>

funciona bem.Mas isso sofre por não ser modular.O que você realmente quer é algo assim:

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

e mais tarde com seu código no lado java ou no lado C# você chama MakeAClick.É claro que no lado C# faz mais sentido, você apenas ClientID está lá.

Talvez este seja o verdadeiro problema do código que você está revisando.

Uma abordagem muito melhor seria usar ClientIDMode e configurá-lo para static.Você pode até configurá-lo para uma página específica ou globalmente no arquivo web.config.Então você nunca mais terá que lidar com esse problema e seu JQuery ficará muito mais limpo.

Topo da página:

<%@ Page Title="" ClientIDMode="Static" Language="C#" CodeBehind="..." Inherits="WebApplication1.WebForm2"  %>

Somente no controle:

<asp:Panel runat="server"  ClientIDMode="Static"></asp:Panel>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top