2008-09-02 4 views
20

私は情報アーキテクトとJavaScript開発者ですが、最近はバックエンドコーディングに戻っています。また、HTMLプロトタイプをC#ベースのCMSと統合して動作させようとしている間に、フォーム要素に対して.NETによってHTML ID属性が任意に書き換えられるというプログラマーに激怒してきました。.NET食べているIDを停止することはできますか?

.NETの変更IDのコードビハインドの理由を理解できますが、たとえば開発中にIDを使用できなくなったという事実を理解できます。 jQueryの強化されたインターフェイスは、いくつかの摩擦を引き起こしています。これを回避するには何ができますか?

私はクラス属性を代わりに使用しようとしましたが、実際にはそれが意味するものではなく、実際にレンダリングされたソースを効果的に変更するという問題を回避しません。また、CSSは現在ではあまり役に立たず、作成や保守が効率的ではないということも意味します。

大歓迎任意のヒントやアドバイス - 以下少数の眠れぬ夜のために何...

答えて

25

短い答えは、Webフォームに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> 

それは私が知っているハックですが、それは動作します。 (私はのために注意しなければならない非開始、私は$そこにID方式により取得プロトタイプを使用しています)

+0

ます」もちろん、そのサーバータグの周りに引用符が必要です。なぜこれがハックなのかわかりません。それは私がずっと使っている正当なテクニックです。これがサーバータグやClientIDのようなものです。 – harpo

+0

ハックのように感じるのはちょっと面倒だからね。私はかなり彼らの静的で、予測可能なidのコントロールにjavascriptと話すことができる –

+0

私はまた、このアプローチを常に使用します。私は通常、headタグ(スタンドアロンページ上)またはasp:ContentPlaceHolder(マスターのheadタグ内)に書き込むasp:Contentコントロール内のすべての "動的"変数を宣言します。少なくとも動的IDを含むすべての変数を1つの場所に保持します。 –

4

は、.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" /> 
+0

一つのことがあるアダプター、および.browserファイル –

12

一つの方法は、オーバーライドすることであるIDの手動:

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

Rick Strahl wrote a blog postにいくつかのより多くの情報を持ちますそのアプローチ。

7

ASP.Net MVCを見てください。これはASP.Netがデフォルトで生成するオーバーキルオブジェクト階層に対応しています。

このサイトはMVCで書かれています(私は思う) - 構造を見てください。私は新しいプロジェクトに取り組んでいましたが、最初に検討するでしょう

もしあなたが基本的なASP.Netに悩まされているなら、ClientIDとUniqueIDを上書きすることに注意してください。

私が見つけた最良の方法は、読めないClientIDをJavascriptに渡すことです。

1

個人的には、サーバーサイドのASP.NET「マジック」(私はまだMS MVCのものをまだ使用していません)とクライアント側のコードをブリッジするために開発した一連のメソッドを使用します。起こるID。

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

だから、あなたのサーバー側のコードであなたは、単にこれを呼び出して、あなたがのために友好名前を使用したいコントロールのインスタンスに渡します。ここまたは有用であることが証明されない場合があり一つです。言い換えれば、のデザイン時にのIDが "m_SomeTextBox"のテキストボックスがあり、その同じ名前を使用してJavaScriptを作成できるようにするには、サーバーサイドコードでこのメソッドを呼び出します。

RegisterControlClientID(m_SomeTextBox); 

そして、クライアント上で、次のレンダリング:JavaScriptコードのすべてがASP.NETが変数に名前を付けることを決定したもののかなり無知可能な方法

var m_SomeTextBox = "ctl00_m_ContentPlaceHolder_m_SomeTextBox"; 

。確かに、ページにコントロールのインスタンスが複数ある場合(たとえば、それらのインスタンス内にm_SomeTextBoxのインスタンスを持つ複数のユーザーコントロールを使用するため)、このメソッドにはいくつかの注意点があります。あなたの最も基本的なニーズに役立ちます。

1

私が通常行っていることは、フィールドの名前を受け取る一般的な関数を作成することです。これは、通常の "asp.net"プレフィックスを追加し、オブジェクトを返します。それと

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

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

あなたはjQueryのを使用している場合、あなたは、あなたがあなたのページの要素をターゲットにあなたの処分でCSS selectors and jQuery custome selectorsの負荷を持っているjQueryの

中のコール
$(o('buttonId')).bind('click', function() { alert('hi); }); 
0

のこの種を使用することができます。それは変更することができますので、あなたは間違いなく、あなたのCSSにハードコードにasp.net-生成されたIDを使用しない

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

:だからむしろそれのidで送信ボタンを取り上げるよりも、あなたのような何かを行うことができますコントロールツリーが変更されるような方法でページ上のものを並べ替えるならば。

CSS IDがその場所にあることは間違いありません。そのため、クラスを使用するだけの提案は無視されます。

ここに記載されているさまざまなjavascriptのハックは、小さな問題では残酷です。クラスから継承し、IDプロパティをオーバーライドします。そして、あなたがやりたいことがいくつかのCSSをリファクタリングしているときに、MVCに切り替えることを提案することは確かに役に立ちません。

CSSでターゲティングするdivとspanを別々にしてください。 IDを使用する場合は、ASP.NETコントロールを直接ターゲットにしないでください。

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

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

が問題ありません。しかし、これはモジュール化されていないことに悩まされています。あなたがMakeAClickを呼び出して、Java側のコードやC#側で

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

し、後で:何が本当に欲しいのはこのようなものです。もちろん、C#側ではもっと意味があります。クライアントIDだけです。

おそらく、これはレビューしているコードの実際の問題です。

0

もっと良いアプローチは、ClientIDModeを使用してstaticに設定することです。特定のページに設定することも、web.configファイル内でグローバルに設定することもできます。その後、この問題を再び処理する必要はなく、JQueryはもっとクリーンです。

ページのトップへ:制御のみで

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

:リストボックスコントロールのためのあなたにも必要になります

<asp:Panel runat="server" ClientIDMode="Static"></asp:Panel> 
関連する問題