Posso interrompere .NET eating IDs?

Al giorno d’oggi sono un architetto dell’informazione e uno sviluppatore JavaScript, ma recentemente ho ricominciato a scrivere sul back-end. E, mentre cercavo di ottenere un prototipo HTML integrato e funzionante con il nostro CMS basato su C #, sono venuto alle mani con i nostri programmatori sugli attributi dell’ID HTML che venivano arbitrariamente riscritti da .NET per gli elementi del modulo.

Riesco a capire il ragionamento code-behind di .NET che cambia ID, ma il fatto che non si possono più usare ID quando si cerca di sviluppare, ad esempio, interfacce migliorate jQuery sta causando qualche attrito. Cosa posso fare per aggirare questo problema?

Ho provato a utilizzare l’attributo class invece, ma questo è davvero schifoso, non è quello che è destinato e non aggira il problema di .NET, cambiando in modo efficace la fonte renderizzata al volo. Significa anche che i CSS ora sono meno utili e meno efficienti da creare e mantenere.

Qualche consiglio o consiglio molto apprezzato – qualsiasi cosa per poche notti insonni …

La risposta breve è no, con webforms l’ID può sempre essere riscritto a seconda del nidificazione dell’elemento. Puoi accedere all’ID tramite la proprietà ClientID, in modo da poter impostare gli ID in variabili in uno script alla fine della pagina / controllo e quindi inserirli in jQuery.

qualcosa come questo:

Click Me  

È un trucco, lo so, ma funzionerà. (Dovrei notare per i non iniziati, sto usando il metodo Prototype $ get by id lì)

Un metodo è quello di sovrascrivere manualmente gli ID:

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

Rick Strahl ha scritto un post sul blog con alcune ulteriori informazioni su tale approccio.

Guarda ASP.Net MVC: risolve le gerarchie di oggetti sovrascritte che ASP.Net genera per impostazione predefinita.

Questo sito è scritto in MVC (penso) – guarda la sua struttura. Se stavo lavorando a un nuovo progetto in questo momento, lo considererei prima

Se sei bloccato con ASP.Net di base, fai attenzione a ignorare ClientID e ID univoco: tende a interrompere molti controlli web.

Il modo migliore che ho trovato è quello di passare il ClientID illeggibile al Javascript.

È ansible estendere i controlli .net e farli restituire gli ID effettivi quando vengono chiamate le proprietà correlate.

ClientID è l’attributo id e UniqueID è l’attributo name degli elementi html. Quindi, quando crei una casella di testo simile alla seguente e utilizzandola al posto della casella di testo nel framework, rendi id e il rendering degli attributi del nome come l’id del lato server.

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

Per usare questo nuovo controllo utente, in pratica registra questo controllo come faresti per un controllo utente personalizzato (puoi farlo in web.config in modo da non doverlo fare in tutte le tue pagine):

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

E usalo come se usassi una casella di testo:

  

Personalmente, utilizzo un insieme di metodi che ho sviluppato per creare un collegamento tra il lato server ASP.NET “magico” (devo ancora utilizzare il materiale MS MVC ancora) e il mio codice lato client a causa del munging degli ID che accade . Eccone uno che può o non può rivelarsi utile:

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

Pertanto, nel codice lato server è sufficiente chiamare questo e passare l’istanza di un controllo per il quale si desidera utilizzare un nome più amichevole per. In altre parole, durante la fase di progettazione , potresti avere una casella di testo con l’ID di “m_SomeTextBox” e vuoi essere in grado di scrivere il tuo JavaScript usando lo stesso nome – semplicemente chiameresti questo metodo nel tuo codice lato server:

 RegisterControlClientID(m_SomeTextBox); 

E poi sul client viene reso il seguente:

 var m_SomeTextBox = "ctl00_m_ContentPlaceHolder_m_SomeTextBox"; 

In questo modo tutto il tuo codice JavaScript può essere abbastanza ignorante di ciò che ASP.NET decide di nominare la variabile. Certo, ci sono alcune avvertenze su questo, come quando si hanno più istanze di un controllo su una pagina (a causa dell’uso di più istanze di controlli utente che hanno tutte un’istanza di m_SomeTextBox al loro interno, ad esempio), ma generalmente questo metodo può essere utile per i tuoi bisogni più elementari.

Quello che faccio di solito è creare una funzione generale che riceve il nome del campo. Aggiunge il solito prefisso “asp.net” e restituisce l’object.

 var elemPrefix = 'ctl00-ContentPlaceHolder-'; //replace the dashes for underscores var o = function(name) { return document.getElementById(elemPrefix + name) } 

Con questo puoi usare questo tipo di chiamate in jQuery

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

Sicuramente non vuoi codificare l’ID generato da asp.net nel tuo CSS, perché può cambiare se riorganizzi le cose sulla tua pagina in modo tale che la tua struttura di controllo cambi.

Hai ragione che gli ID CSS hanno il loro posto, quindi ignorerei i suggerimenti per usare solo le classi.

I vari hack javascript descritti qui sono eccessivi per un piccolo problema. Quindi eredita da una class e sovrascrive la proprietà ID. E non è certamente utile suggerire il passaggio a MVC quando tutto ciò che si vuole fare è refactoring di alcuni CSS.

Basta avere div separate e span che scegli come target con i CSS. Non indirizzare direttamente i controlli ASP.NET se si desidera utilizzare ID.

  
......

Se utilizzi jQuery, hai a disposizione numerosi selettori CSS e selettori jQuery per selezionare gli elementi sulla tua pagina. Quindi, piuttosto che scegliere un pulsante di invio dal suo id, potresti fare qualcosa del tipo:

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

Posso vedere come il sistema .NET si sente meno intuitivo, ma dargli una possibilità. Nella mia esperienza in realtà finisce per creare un codice più pulito. Sicuro

 Click Me  

funziona bene. Ma questo soffre di non essere modulare. Quello che vuoi veramente è qualcosa del genere:

  

e successivamente con il tuo codice sul lato java o sul lato C # che chiami MakeAClick. Ovviamente sul lato C # ha più senso, è solo ClientID lì.

Forse questo è il vero problema con il codice che stai recensendo.

Un approccio molto migliore sarebbe utilizzare ClientIDMode e impostarlo su static . Puoi persino impostarlo per una pagina specifica o globalmente nel file web.config. Quindi non dovrai più risolvere questo problema e il tuo JQuery è molto più pulito.

Inizio pagina:

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

Solo sul controllo: