エントリー
ASP.NETの4番目のバージョンの革新の1つは、クライアント上のマークアップ要素の識別子の形成を制御する機能です。 以前は、フレームワークは各要素に一意の識別子を設定していました。 これにより、定義した識別子がctl00_MasterPageBody_ctl01_Textbox1のようなものに変換されました。
問題
各要素の識別子の一意性を確保する必要がある場合、クライアント側での識別子の変更は正常に機能しますが、このような識別子を使用すると、クライアントスクリプトを操作する必要がある人を混乱させる可能性があります。 また、ASP.NETを使用している場合、これらの問題に遭遇する可能性が最も高くなります。 問題は、スクリプトの実行中に識別子が何であるかを正確に知ることができないため、クライアントスクリプトの記述が困難になることです。 さらに、ページの変更、コントロールの追加または削除により、他の識別子が生成される場合があります。
古いスタイルのソリューション
ASP.NETを長期間使用している場合は、説明されている問題を解決する方法を知っています。 各コントロールには、この要素のクライアント識別子を定義する読み取り専用プロパティClientIDが含まれています。 スクリプトを動的に追加するときにサーバーコードでこのプロパティを使用できます。より一般的な場合は、マークアップコード(古いASPスタイル)でこのプロパティを使用して、クライアント側のスクリプトを実装できます。
<script type= "text/javascript" >
function DoSomething(){
alert( '<%= Control.ClientID %>' );
}
</script>
* This source code was highlighted with Source Code Highlighter .
ASP.NET 4.0のソリューション
まず、フレームワークの4番目のバージョンでこの問題に取り組むことにした理由を説明しましょう。 スクリプトの成長に伴うクライアント側の識別子の一意性のサポートの実装により、コードにはますます多くのトリックが含まれることになりました。 このようなシステムでは、多数の外部スクリプトファイルを使用して多くのコントロールの作業を実装する通常の方法はありませんでした。 さらに、開発者がこの一意の識別子割り当てシステムを制御するためのメカニズムが必要でした。 開発者は、それが必要かどうかにかかわらず、すべてを制御するのが好きです。これが私たちの性質です:)。 当社が提供するソリューションには、開発者が識別子システムを完全に制御するために使用できる4つのモードが含まれています。 コントロールのIDプロパティは、インストールされたClientIDModeモードに基づいて変更され、それに応じて、クライアント側で識別子を生成します。
モードとその機能
各コントロール(PageおよびMasterPageを含む)に対して、ClientIDModeと呼ばれる新しいプロパティが追加されました。これは、クライアントIDを生成するメカニズムを選択するために使用されます。
< asp:Label ID ="Label1" runat ="server" ClientIDMode ="[Mode Type]" />
* This source code was highlighted with Source Code Highlighter .
モード
- レガシー(非推奨):ClientIDModeがコントロールツリーのどこにも設定されていない場合のデフォルトモード。 このモードは、フレームワークのバージョン2.0で識別子がどのように形成されたかと同じです(3.0および3.5など)。 このモードは、ctl00_MasterPageBody_ctl01_Textbox1と同様のIDを生成します。
- 継承(継承):これは、コントロールのデフォルトモードです。 この場合、モードを取得するには、親要素のClientIDMode値を使用します。 各コントロールにこのプロパティを設定する必要はありません。デフォルトで設定されているため、要素のメカニズムをあるモードから親に固有のモードに変更する必要がある場合に使用できます。
- 静的:このモードは、あなたが思ったとおりに動作し、静的IDを設定します。 これは、コントロールのIDに指定したものがクライアント側の識別子に使用されることを意味します。 注意、これは、静的なClientIDModeが繰り返し要素を持つコントロールで使用される場合、開発者はクライアント側で識別子の一意性を独立して保証する責任があることを意味します。
- 予測可能:このモードは、一意性を確保する必要があるが、予測どおりに実行する必要がある場合に使用されます。 このモードを使用する最も一般的な例は、データソースにバインドされているコントロールです。 この場合、フレームワークはコントロールの階層全体を調べ、各要素(静的要素を除く)に親要素のIDの形式でプレフィックスを割り当てます。 コントロールがデータバインディングのあるコントロール内にある場合、いくつかの値の形式のサフィックスがIDに追加されます。 これらの値を管理するには、ClientIDRowSuffixプロパティを使用します(例を参照)。 このモードは、Gridview1_Label1_0と同様の識別子値を生成します。
例
レガシーモード
レガシーモードは、フレームワークがバージョン2.0で行ったのと同じ方法で、クライアント側でIDを生成します。
マークアップ:
< asp :TextBox ID ="txtEcho" runat ="server" Width ="65%" ClientIDMode ="Legacy" />
* This source code was highlighted with Source Code Highlighter .
結果:
< input id ="ctl00_MasterPageBody_ctl00_txtEcho" style ="width: 65%"
name ="ctl00$MasterPageBody$ctl00$txtEcho" />
* This source code was highlighted with Source Code Highlighter .
静的モード
静的モードは、すべてのClientIDModeモードの中で最も単純です。これにより、サーバーコントロールに設定されたIDと同じクライアント側のIDを取得できます。 繰り返しますが、静的なClientIDModeが繰り返し要素を持つコントロールで使用される場合、開発者はクライアント側で一意の識別子を作成する必要があることに注意する必要があります。
マークアップ:
< asp:TextBox ID ="txtEcho2" runat ="server" Width ="65%" ClientIDMode ="Static" />
* This source code was highlighted with Source Code Highlighter .
結果:
< input id ="txtEcho2" style ="width: 65%" name ="ctl00$MasterPageBody$ctl00$txtEcho2" />
* This source code was highlighted with Source Code Highlighter .
予測可能モード
予測可能なモードは、問題の核心に当たります。 以前は、フレームワークは一意のIDを生成して、たとえば、最も一般的なケースでは、データソースバインディングを持つコントロール内で識別子の一致を回避していました。 予測可能モードは、そのような瞬間のために特別に設計されていますが、他の場合にも使用できます。 予測可能モードを使用するには、3つのオプションがあります。各オプションはClientIDRowSuffixプロパティで指定され、各要素に使用するサフィックスを示します。 ClientIDRowSuffixはコントロールのキーフィールドのコレクションの値を使用するため、コントロールにそのようなコレクションが含まれていない場合、このプロパティは機能しません。 このプロパティが設定されていないか使用できない場合、要素インデックスの数値が接尾辞に使用されます。
1. ClientIDRowSuffixは定義されていません。これは、コントロールにキーフィールドのコレクション(Repeaterなど)がない場合に使用できます。 フレームワークは、祖先IDとして要素にプレフィックスを割り当て、単純な序数値としてサフィックスを割り当てることに注意してください。
マークアップ:
< asp:GridView ID ="EmployeesNoSuffix" runat ="server" AutoGenerateColumns ="false"
ClientIDMode ="Predictable" >
< Columns >
< asp:TemplateField HeaderText ="ID" >
< ItemTemplate >
< asp:Label ID ="EmployeeID" runat ="server" Text ='<%# Eval("ID") %>' />
</ ItemTemplate >
</ asp:TemplateField >
< asp:TemplateField HeaderText ="Name" >
< ItemTemplate >
< asp:Label ID ="EmployeeName" runat ="server" Text ='<%# Eval("Name") %>' />
</ ItemTemplate >
</ asp:TemplateField >
</ Columns >
</ asp:GridView >
* This source code was highlighted with Source Code Highlighter .
結果:
< table id ="EmployeesNoSuffix" style ="border-collapse: collapse" cellspacing ="0" rules ="all" border ="1" >
< tbody >
< tr >
< th scope ="col" > ID </ th >
< th scope ="col" > Name </ th >
</ tr >
< tr >
< td >< span id ="EmployeesNoSuffix_EmployeeID_0" > 1 </ span ></ td >
< td >< span id ="EmployeesNoSuffix_EmployeeName_0" > EmployeeName1 </ span ></ td >
</ tr >
...
< tr >
< td >< span id ="EmployeesNoSuffix_EmployeeID_8" > 9 </ span ></ td >
< td >< span id ="EmployeesNoSuffix_EmployeeName_8" > EmployeeName9 </ span ></ td >
</ tr >
</ tbody >
</ table >
* This source code was highlighted with Source Code Highlighter .
2. ClientIDRowSuffixが指定されます。この場合、サフィックス値のキーフィールド値の検索が実行されます。
マークアップ:
< asp:GridView ID ="EmployeesSuffix" runat ="server" AutoGenerateColumns ="false"
ClientIDMode ="Predictable" ClientIDRowSuffix ="ID" >
< Columns >
< asp:TemplateField HeaderText ="ID" >
< ItemTemplate >
< asp:Label ID ="EmployeeID" runat ="server" Text ='<%# Eval("ID") %>' />
</ ItemTemplate >
</ asp:TemplateField >
< asp:TemplateField HeaderText ="Name" >
< ItemTemplate >
< asp:Label ID ="EmployeeName" runat ="server" Text ='<%# Eval("Name") %>' />
</ ItemTemplate >
</ asp:TemplateField >
</ Columns >
</ asp:GridView >
* This source code was highlighted with Source Code Highlighter .
結果:
< table id ="EmployeesSuffix" style ="border-collapse: collapse" cellspacing ="0" rules ="all" border ="1" >
< tbody >
< tr >
< th scope ="col" > ID </ th >
< th scope ="col" > Name </ th >
</ tr >
< tr >
< td >< span id ="EmployeesSuffix_EmployeeID_1" > 1 </ span ></ td >
< td >< span id ="EmployeesSuffix_EmployeeName_1" > EmployeeName1 </ span ></ td >
</ tr >
...
< tr >
< td >< span id ="EmployeesSuffix_EmployeeID_9" > 9 </ span ></ td >
< td >< span id ="EmployeesSuffix_EmployeeName_9" > EmployeeName9 </ span ></ td >
</ tr >
</ tbody >
</ table >
* This source code was highlighted with Source Code Highlighter .
3. ClientIDRowSuffixが指定されていますが、単一の値ではなく、いくつかが指定されています。 これは、接尾辞が複数の値で構成されるという事実につながります。
マークアップ:
< asp:GridView ID ="EmployeesCompSuffix" runat ="server" AutoGenerateColumns ="false"
ClientIDMode ="Predictable" ClientIDRowSuffix ="ID, Name" >
< Columns >
< asp:TemplateField HeaderText ="ID" >
< ItemTemplate >
< asp:Label ID ="EmployeeID" runat ="server" Text ='<%# Eval("ID") %>' />
</ ItemTemplate >
</ asp:TemplateField >
< asp:TemplateField HeaderText ="Name" >
< ItemTemplate >
< asp:Label ID ="EmployeeName" runat ="server" Text ='<%# Eval("Name") %>' />
</ ItemTemplate >
</ asp:TemplateField >
</ Columns >
</ asp:GridView >
* This source code was highlighted with Source Code Highlighter .
結果:
< table id ="EmployeesCompSuffix" style ="border-collapse: collapse" cellspacing ="0" rules ="all" border ="1" >
< tbody >
< tr >
< th scope ="col" > ID </ th >
< th scope ="col" > Name </ th >
</ tr >
< tr >
< td >< span id ="EmployeesCompSuffix_EmployeeID_1_EmployeeName1" > 1 </ span ></ td >
< td >< span id ="EmployeesCompSuffix_EmployeeName_1_EmployeeName1" > EmployeeName1 </ span ></ td >
</ tr >
...
< tr >
< td >< span id ="EmployeesCompSuffix_EmployeeID_9_EmployeeName9" > 9 </ span ></ td >
< td >< span id ="EmployeesCompSuffix_EmployeeName_9_EmployeeName9" > EmployeeName9 </ span ></ td >
</ tr >
</ tbody >
</ table >
* This source code was highlighted with Source Code Highlighter .
おわりに
クライアント側で識別子の生成を完全に制御する機能は、誰もが望む機会です。 良い解決策を見つけたと確信しており、大量のクライアントコードを作成するために必要な機能を開発者に追加すると考えています。 このCTPには、PDC 2008で発表された暫定版が用意されています。詳細と詳細な説明については、Scott Galloway によるこの投稿をお読みください。