2009-08-05 10 views
5

Tengo cerca de 600 referencias de código similar a lo siguiente ...Cómo utilizar jQuery, seleccione el elemento de identificación y ASP.NET sin poner ctl00_ todas partes en el código

$("#ctl00_ContentMainPane_eliteUser").html 

y cambiaron la plantilla maestra , solo para encontrar que todo el código se había roto, debido a que la jerarquía de control cambiaba.

Todo Javascript se incluye en archivos separados, así que no puedo usar el código como este ...

$("#<%= eliteUser.clientID%>").html 

Quiero tener una buena solución para solucionar este problema por lo que después de la fijación de una vez, lo Don No tiene que modificar todo el código si la plantilla cambia en el futuro.

+1

Más problemas se han identificado aquí: http://stackoverflow.com/questions/1232641 – digiguru

Respuesta

8

¿Qué hay de definición de una función JavaScript en su página maestra como:

function getContainerId() { 
    return "<%=ContentMainPane.ClientID %>"; 
} 

Luego, en sus archivos JavaScript comprendidos hacer algo como esto:

$("#" + getContainerId() + "_eliteUser"); 
1

Por lo que sé, asp.net no se mete con los nombres de las clases. Agregue un nombre de clase a su control y use ese nombre como referencia en su código.

2

se puede hacer algo como esto:

$("input[id*=eliteUser]").html() 

Pero si tiene varios controles que terminan sus identificaciones en eliteUser - no va a funcionar.

3

Una forma es usar un objeto js variables que se escribe en la parte superior de cada página. Su js externo puede hacer referencia al objeto de configuración con la propiedad deseada. De esta manera, puede cambiar la identificación en sus páginas aspx sin tener que codificar nada en los archivos js externos.

A continuación, puede exponer un método de página base o materpage que permite que cada página agregue los elementos de identificación de control a una lista. El método base tiene la responsabilidad de escribir el script pageVars en la parte superior de cada página.

Rick Strahl habla de este here

que prefieren este método como sigue recibiendo los beneficios de selectores rápidos.

por ejemplo

Si se obtiene el aspx a escribir el siguiente guión.

var pageVars = { 
    idList: { 
     eliteUser : 'ctl00_ContentMainPane_eliteUser', 
     normalUser : 'ctl00_ContentMainPane_normalUser', 
     powerUser : 'ctl00_ContentMainPane_powerUser', 
     ..... 
    } 
}; 

Luego, en sus js externos

$('#' + pageVars.idList.eliteUser) 
$('#' + pageVars.idList.powerUser)....etc 
0

Esto es un problema que entiendo que se tratará en la próxima versión de Visual Studio, sin embargo, me doy cuenta de que esto no lo ayudará.

La forma en que abordamos en nuestro proyecto era algo línea de esto:

$.extend({ 
    clientID: function(id) { 
     return $("[id$='_" + id + "']"); 
    } 
}); 

Y el código que usó:

statusBar = $.clientID("MSS_MESS_LINE_Static") 
+0

Pero termina con selectores de perro lento, ya que se acercará CADA elemento en la página con una identificación y luego filtrar. – redsquare

+0

¿Tiene un enlace a cómo "visual studio" resolverá esto? o te refieres al .NET framework? – digiguru

+0

a la mitad de este artículo http://www.mostlyucuc.net/archive/2008/11/03/way-too-too-much-information-on-control-ids-and-asp.net-4.0.aspx – redsquare

2

He estado usando una clase que se extiende WebControl hacer esencialmente lo mismo que RedSquare's suggestion. He leído el suggestion on this blog

/// <summary> 
/// Custom Web control that renders two JavaScript functions out into the page 
/// so that defined control IDs can be used to get a reference to HTML DOM elements 
/// </summary> 
[DefaultProperty("Text")] 
[ToolboxData("<{0}:ClientIdHandler runat=\"server\"></{0}:ClientIdHandler>")] 
public class ClientIdHandler : WebControl 
{ 
    private StringBuilder _builder = new StringBuilder(); 

public ClientIdHandler(){} 


/// <summary> 
/// Renders the ClientID of the control in JavaScript function "clientId" to the specified writer. 
/// </summary> 
/// <param name="output">A <see cref="Control"/> whose ClientID will be included 
/// in the rendered HTML output.</param> 
public void AddControl(Control c) 
{ 
    _builder.AppendFormat(" case '{0}': return '{1}'; break;" + Environment.NewLine, c.ID, c.ClientID); 
} 

/// <summary> 
/// Overrides the Render method to prevent a Start and End <see cref="HtmlTextWriterTag"/> 
/// being rendered in the HTML for the control. 
/// </summary> 
/// <param name="output">A <see cref="HtmlTextWriter"/> that represents 
/// the output stream to render HTML content on the client.</param> 
protected override void Render(HtmlTextWriter writer) 
{  
    RenderContents(writer); 
} 


/// <summary> 
/// Renders the contents of the control to the specified writer. 
/// </summary> 
/// <param name="output">A <see cref="HtmlTextWriter"/> that represents 
/// the output stream to render HTML content on the client.</param> 
protected override void RenderContents(HtmlTextWriter output) 
{ 
    output.Write("<script type=\"text/javascript\"> " + Environment.NewLine); 
    output.Write("function clientId(id) {" + Environment.NewLine); 
    output.Write("switch (id) {" + Environment.NewLine); 
    output.Write(_builder.ToString()); 
    output.Write("  }" + Environment.NewLine); 
    output.Write("}" + Environment.NewLine); 
    output.Write("function getElementByClientId(id) {" + Environment.NewLine); 
    output.Write(" return document.getElementById(clientId(id));" + Environment.NewLine); 
    output.Write("}" + Environment.NewLine); 
    output.Write("</script>" + Environment.NewLine); 
} 
} 

A continuación, se pueden utilizar en la página aspx o de código subyacente

protected override void OnInit(EventArgs e) 
    { 
     ClientIdHandler clientIds = new ClientIdHandler(); 
     clientIds.AddControl(myControl); 

     this.Controls.Add(clientIds); 

     base.OnInit(e); 
    } 

Qué va a hacer el siguiente en la página

<script type="text/javascript"> 
function clientId(id) { 
switch (id) { 
    case 'myControl': return 'ctl00_Main_myControl'; break; 
    } 
} 
function getElementByClientId(id) { 
    return document.getElementById(clientId(id)); 
} 
</script> 

Así que en su JavaScript externa archivo, puede usar el siguiente

// for jQuery selectors 
var myControl = $('#' + clientId('myControl')); 

// for vanilla JavaScript 
var myControl = getElementByClientId('myControl')); 
1

Estoy usando ScriptManager.RegisterStartupScript para obtener todos los ClientID que necesito.

  1. Defina las variables de javascript en la 'cabecera' de la página para almacenar los ID.
  2. Uso RegisterStartupScript en Page_Load para asignar valores a las variables como sigue:

cadena myScript = String.Format ("window.onload = function() {id1 = {0}, id2 = {1}, id3 = {2}} ", Control1.ClientID, Control2.ClientID, Control3.ClientID);

ScriptManager.RegisterStartupScript (Página, Page.GetType(), "SomeKey", myScript, true);

Cuestiones relacionadas