11

そのため、レイアウトが進化して複雑になったケースがあります。のような通常のものがあり@section styleIncludes{ ... }ます。次に、現在のページのブレッドクラムの構造のように、各ページがオプションで (ただしほとんどの場合) 指定できるあらゆる種類のものを定義する他のセクションがあります。これらすべてがセクションである理由は、それらがレイアウトの構造に埋め込まれているためです。

前のページの正確なスペルを覚えたり、断片的なコピー/貼り付けをしたりするのではなく、8 つほどの異なるセクションがあるため、以前のページのコピーを作成していることに気づきました。

これらの流暢な API を作成して、それぞれがオブジェクト自体を返す 8 つの関数を持つオブジェクトを作成して、Sections.Style(some MVC text template または razor delgate ?).パンくず(など)

主な目的は、完全な入力やコピー/貼り付けに頼るのではなく、ガイド付きの方法でこれらのセクションをコーディングし、名前を厳密に入力できるようにすることです。

ただし、かみそりの拡張機能/ヘルパーは MvcHtmlString を返します。@section はまったく異なるもので表されると思います。

私のために完全な解決策を書くようにあなたに頼むのではなく、先行する方法についてのいくつかのアイデアです.

@section宣言を表すためにヘルパーが返すべきオブジェクトはどれですか? つまり、MvcHtmlString のアナロジーです。

Style や Breadcrumb など、流暢なメソッドのパラメータ タイプを提案してください。 渡された razor が、セクション宣言の中かっこで razor を記述するのと同様の機能であることを望みます。たとえば、通常のセクション宣言と同じように、カミソリ ページで宣言されたローカル変数にアクセスできます。文字列連結のようなものはしたくない.SomeSection("<div...>Bunch of html stuffed in a string</div>")

言い換えれば、私のcshtmlページの多くが次のようなもので始まる場合

@{
  string title = "Edit Person"
  ViewBag.Title = title;
}
@section styles{
  .someOneOffPageSpecificStyle { width:59px }
}
@section javascript{
  //javascript includes which the layout will place at the bottom...
}
@section breadcrumb{
  <a ...>Parent Page</a> &gt; <a ...>Sub Page</a> &gt; @title
}

私はこのような流暢な API のようなものを使いたいと思っています。これは、結果として得られるコードのスタイルのためではなく、インテリセンスが支援するため、コードの記述が容易になり、タイプミスなどの問題が発生しないためです。

@{
  string title = "Edit Person"
  ViewBag.Title = title;
}
@Sections
.Styles(@<text>
  .someOneOffPageSpecificStyle { width:59px }
</text>)
.Javascript(@<text>
  //javascript includes which the layout will place at the bottom...
</text>)
.Breadcrumb(@<text>
  <a ...>Parent Page</a> &gt; <a ...>Sub Page</a> &gt; @title
</text>)
4

3 に答える 3

2

ほとんどの場合、これは不可能です (セクションを使用)。

まず、MVC が内部でどのように機能するかを理解する必要があります。cshtml ファイルを作成しますが、これらのファイルは最終的にインスタンス化される.Net クラスにコンパイルされ、メソッドが実行され (最低限Execute() )、(ほとんどの場合) IIS が返す応答バッファーに書き込みます。 ( RenderActionの動作とまったく同じではないにしても非常に似ています-子アクション メソッドを呼び出し、結果を親ビューにインラインでレンダリングします)。HtmlHelpers (または任意のカスタム ヘルパー) は、インスタンス化されたクラスから (デリゲートとして) 呼び出されるだけなので、cshtml ファイルのコードがコンパイルされた後にのみ実行できます。

System.Web.Razor.Generator.SectionCodeGenerator には、セクションを作成するための文字列定義が必要です。したがって、セクションを定義する場合、ファイルがコンパイルされる前に文字列がcshtmlファイルに存在する必要があります.HtmlHelperまたは/およびカスタムヘルパーはファイルがコンパイルされるまで実行されないため、クラスまたはオブジェクトを記述する方法はありませんコンパイルする前に cshtml ファイルを更新できます。

できることは、独自の HtmlHelper または他のカスタム ヘルパーを記述して、セクションが提供するものと同様のことを行うことです (実際にはセクションを使用しません)。たとえば、部分的なビューやテンプレート (セクションではできない) から Javascript を作成する必要があったため、これを作成しました。セクションを使用する必要がある場合、これは役に立たない可能性があります。

次のコードは単なる例であり、かみそりが実際にどのように機能するかではありません (コードを調べた後)。しかし、この例を意味のあるものにするために、かみそりのようなコードと命名規則を使用します。

レイアウト.cshtml

<html>
<body>
@RenderSection("MySectionName")

@RenderBody();
</body>
</html>

インデックス.cshtml

@{
  _layout = "layout";
}

@section MySection {
  <div>MySection</div>
}

<div>My Body</div>

次のようなクラスにコンパイルされる可能性があります。

public class app_aspnet_layout : System.Web.Mvc.WebViewPage
{

  public Execute()
  {
    throw new NotImplementedException();
  }

  public void ExecutePageHierarchy(WebPageContext pageContext, 
                                   TextWriter writer)
  {
    writer.Write("<html>")
    writer.Write("<body>")

    var section = pageContext.SectionWriters["MySectionName"];
    section();

    pageContext.View.ExecutePageHierarchy(null, writer)

    writer.Write("</body>")
    writer.Write("</html>")
  }
}

public class app_aspnet_index : System.Web.Mvc.WebViewPage
{ 
  // generated from the _layout Definition
  private WebViewPage startPage = new app_aspnet_layout();

  public Execute()
  {
     WebPageContext pageContext = new WebPageContext();
     pageContext.View = this;

     pageContext.SectionWriters.Add("MySectionName", 
                                    this.Section_MySectionName);

     var writer = HttpContext.Current.Response.Stream.AsTextWriter();

     if (startPage != null)
     {
       startPage.ExecutePageHierarchy(pageContext, writer);
     }
     else
     {
       this.ExecutePageHierarchy(pageContext, writer);
     }
  }

  // html generated from non-section html
  public void ExecutePageHierarchy(WebPageContext pageContext, 
                                   TextWriter writer)
  {
    writer.Write("<div>My Body</div>");
  }

  public void Section_MySectionName(TextWriter writer)
  {
    writer.Write("<div>MySection</div>");
  }
}
于 2013-07-25T00:51:03.817 に答える
0

t4 テンプレートを使用して、別の方向から問題に取り組むことができます。

レイアウトの構造がかなり安定していて (つまり、頻繁にセクションを追加したり削除したりしていない)、新しいビューを作成するときに何かをコピーして貼り付けるのをやめたいだけの場合、これはおそらくうまくいくでしょう。仕様に合わせてビューを作成します-リフレクションやその他のロジックを使用して、ビューで非常に賢いことを行うことができます

コードテンプレートをロードするためのナゲットがあります-「コードテンプレート」を検索してください-そしてそれらは非常に簡単に使用できます。

于 2013-07-30T02:57:12.200 に答える