web-dev-qa-db-ja.com

Razor View Engine:複雑なループとHTML

現在のプロジェクトには複雑なHTMLレポートがたくさんあり、行スパンと列スパンを使用してTRとTDの条件付きレンダリングを多数実行しています。

次のようになる場合があります(これは非常に単純化されています)。

<tr>
@foreach (var ourItem in ourList) {
   if (ourItem != ourList.First()) {
      <tr>                
   }
   <td></td>
   </tr>
}

ただし、Razorは、「foreachループに終了「}」文字がありません」と主張しています。 (Visual Studio内)

<tr><text></text>でラップしようとしましたが、これにより、終了}の問題は、実行時にのみ検出されます。「開始タグが一致しない終了タグ「tr」が見つかりました。開始/エンドタグは適切にバランスが取れています。」.

RazorにHTMLをまったく気にしないように説得しながら、この種の条件付きレンダリングを行うにはどうすればよいでしょうか。すべてのループが完了すると、HTMLのバランスが取れます。または、少なくともASP.NET ViewEngineが使用された場合はそうでした。

28
Mikael Östberg

Visual StudioのIntellisenseと構文の強調表示は、最善の方法の1つではありませんが、この場合、条件が満たされない場合、無効なマークアップを取得する可能性があるため、これを非難するべきではないことを警告します。

重要なことは、プロジェクトが正常に実行されることですが、このロジックをHTMLヘルパーに外部化することを検討することもできます。なぜなら、これがビューにあるものの単純化されたバージョンであるとあなたが言っていることが本当なら、私はあなたの実際のコードは見えます。

ビューに非常に多くの条件付きロジックがあるIMHOは、悪用です。 MVCContrib Grid などのHTMLヘルパーまたはコントロールの使用を検討する必要があります。


更新:

次のハックを試すことができます。

<tr>
@foreach (var ourItem in ourList) {
   if (ourItem != ourList.First()) {
      @:<tr>                
   }
   @:<td></td>
   @:</tr>
}
35
Darin Dimitrov

Razorは、一致するタグに依存して、コードとマークアップの間の自動遷移を決定します。 Razorのこの機能を「無効」にすることはできません(少なくとも、Razorパーサーの大部分を書き直さない限り)。

ダリンの提案を使用して回避することができますが、(少なくとも単純化した例からは)なぜあなたの見解をそれほど複雑にする必要があるのか​​はわかりません。代わりに次のコードを書いてみませんか。

@foreach (var ourItem in ourList) {
   <tr>
   <td>...</td>
   </tr>
}

生成されたマークアップでタグのバランスが取れている可能性がありますが、提供したソースにより、その正確性について推論することは非常に困難です。

6
marcind

同様の問題がありました-私のソリューションHtml.Raw( "");

    if (isTrue)
    {
        <text><div></text> }
   ...

    if(isTrue) {
        @Html.Raw("</div>"); // <-- closing tag!
        }
4
Robert Muehsig

行スパンを使用しようとして、次のような構造を取得しようとした場合

<table>
   <tr>
       <td rowspan=2>1:st col</td>
       <td>2:nd col</td>
   </tr>
   <tr>
       <td>2:nd col</td>
   </tr>
</table>

あなたは試すことができます:

@{ 
    var ourList = new List<string> { "1", "2", "3" };
}

<table border=1>
@foreach(var ourItem in ourList){
    <tr>
    @if (ourItem == ourList.First())
    {
        <td rowspan="@ourList.Count()">@ourItem</td>
    }
    <td>@ourItem</td>
    </tr>
}
</table>
4
Wiren