Могу ли я остановить .NET есть идентификаторы? - PullRequest
21 голосов
/ 02 сентября 2008

В настоящее время я торгую информационным архитектором и разработчиком JavaScript, но недавно я снова вернулся к внутреннему кодированию. И, пытаясь интегрировать прототип HTML и работать с нашей CMS на основе C #, я столкнулся с нашими программистами из-за того, что атрибуты HTML ID произвольно переписываются .NET для элементов формы.

Я могу понять аргументы в пользу скрытого кода для изменения идентификаторов .NET, но тот факт, что вы больше не можете использовать идентификаторы при разработке, например. Расширенные интерфейсы jQuery вызывают некоторые трения. Что я могу сделать, чтобы обойти это?

Я попытался использовать вместо этого атрибут класса, но это действительно дерьмово, а не то, для чего он предназначен, и не решает проблему .NET эффективного изменения визуализированного источника на лету. Это также означает, что CSS теперь менее полезен и менее эффективен для создания и поддержки.

Любые советы или советы, которые очень ценятся - что угодно для нескольких менее бессонных ночей ...

Ответы [ 10 ]

25 голосов
/ 02 сентября 2008

Короткий ответ - нет, для веб-форм идентификатор всегда можно переписать в зависимости от вложенности элемента. Вы можете получить доступ к идентификатору через свойство ClientID, поэтому вы можете установить идентификаторы в переменные в скрипте в конце страницы / элемента управления, а затем поместить их в 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>

Это хак, я знаю, но это сработает. (Следует отметить, что для не инициированных я использую метод Prototype $ get by id)

12 голосов
/ 02 сентября 2008

Один из способов - переопределить идентификаторы вручную:

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

Рик Страл написал сообщение в блоге с дополнительной информацией об этом подходе.

7 голосов
/ 02 сентября 2008

Посмотрите на ASP.Net MVC - он обращается к иерархиям объектов уничтожения, которые ASP.Net генерирует по умолчанию.

Этот сайт написан на MVC (я думаю) - посмотрите на его структуру. Если бы я работал над новым проектом прямо сейчас, я бы сначала рассмотрел его

Если вы застряли с базовым ASP.Net, будьте осторожны, переопределяя ClientID и UniqueID - это может привести к поломке многих веб-элементов управления.

Лучший способ, который я нашел, - это передать нечитаемый ClientID в Javascript.

4 голосов
/ 02 сентября 2008

Вы можете расширить элементы управления .net и заставить их возвращать фактические идентификаторы при вызове связанных свойств.

ClientID - это атрибут id, а UniqueID - атрибут имени html-элементов. Поэтому, когда вы создаете текстовое поле, подобное следующему, и используете его вместо текстового поля в платформе, атрибуты id и name отображаются так же, как и идентификатор на стороне сервера.

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" />
1 голос
/ 22 сентября 2008

Вы определенно не хотите жестко кодировать сгенерированный asp.net идентификатор в свой CSS, потому что он может измениться, если вы переставите вещи на своей странице таким образом, что ваше дерево управления изменится.

Вы правы, что CSS-идентификаторы имеют свое место, поэтому я бы проигнорировал предложения просто использовать классы.

Различные хаки javascript, описанные здесь, излишни для небольшой проблемы. Так наследуется от класса и переопределяет свойство ID. И, конечно, бесполезно предлагать перейти на MVC, когда все, что вам нужно, - это рефакторинг CSS.

Просто используйте отдельные элементы div и span, на которые вы нацеливаетесь с помощью CSS. Не используйте целевой элемент управления ASP.NET напрямую, если хотите использовать идентификаторы.

  <div id="DataGridContainer">
     <asp:datagrid runat=server id="DataGrid" >
         ......
     <asp:datagrid>
  </div>
1 голос
/ 06 сентября 2008

Что я обычно делаю, это создаю общую функцию, которая получает имя поля. Он добавляет обычный префикс asp.net и возвращает объект.

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

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

С этим вы можете использовать этот тип вызовов в jQuery

$(o('buttonId')).bind('click', function() { alert('hi); });
1 голос
/ 02 сентября 2008

Лично я использую набор методов, которые я разработал для преодоления серверной "ASP.NET" магии "(я еще не использовал материал MS MVC) и мой код на стороне клиента из-за того, что Идентификаторы, которые происходят. Вот только один, который может или не может оказаться полезным:

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

Итак, в своем коде на стороне сервера вы просто вызываете это и передаете экземпляр элемента управления, для которого вы хотите использовать более дружественное имя. Другими словами, в время разработки у вас может быть текстовое поле с идентификатором «m_SomeTextBox», и вы хотите иметь возможность написать свой JavaScript, используя то же имя - вы просто вызовете этот метод на своем сервере код стороны:

RegisterControlClientID(m_SomeTextBox);

А потом на клиенте выдается следующее:

var m_SomeTextBox = "ctl00_m_ContentPlaceHolder_m_SomeTextBox";

Таким образом, весь ваш код JavaScript может не знать, что ASP.NET решит назвать переменную. Конечно, есть некоторые предостережения, например, когда у вас есть несколько экземпляров элемента управления на странице (из-за использования нескольких экземпляров пользовательских элементов управления, у всех из которых есть, например, экземпляр m_SomeTextBox), но обычно этот метод может быть полезным для ваших самых основных потребностей.

0 голосов
/ 11 февраля 2016

Гораздо лучший подход - использовать ClientIDMode и установить его на static. Вы даже можете установить его для определенной страницы или глобально в файле web.config. Тогда вам больше никогда не придется решать эту проблему, и ваш JQuery станет намного чище.

Начало страницы:

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

Только для управления:

<asp:Panel runat="server"  ClientIDMode="Static"></asp:Panel>
0 голосов
/ 03 декабря 2009

Я вижу, как система .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>

отлично работает. Но это страдает от отсутствия модульности. То, что вы действительно хотите, это что-то вроде этого:

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

, а затем позже с вашим кодом на стороне Java или стороне C # вы вызываете MakeAClick. Конечно, на стороне C # это имеет больше смысла, вы просто ClientID там.

Возможно, это реальная проблема с кодом, который вы просматриваете.

0 голосов
/ 09 сентября 2008

Если вы используете jQuery, у вас есть множество CSS-селекторов и jQuery custome селекторов , которые вы можете использовать для таргетинга элементов на своей странице. Поэтому вместо того, чтобы выбирать кнопку отправки по ее идентификатору, вы можете сделать что-то вроде:

$('fieldset > input[type="submit"]').click(function() {...});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...