UserControl を使用して HTML を生成するためのヒント

高洛峰
リリース: 2017-03-08 15:58:34
オリジナル
1188 人が閲覧しました

ユーザー コントロールは、ASP.NET を使用するプロセスにおいて、aspx ページとは別に、最も一般的なものは ascx です。 ascx は独立したロジックを備えたコンポーネントであり、強力な再利用機能を提供し、合理的に使用すると開発効率を大幅に向上させることができます。ユーザー コントロールを使用して HTML コンテンツを直接生成することは、実際には比較的一般的な手法です (特に AJAX 時代では)。ただし、インターネット上にはこの分野のコンテンツがまだ比較的少ないため、ここでは An を使用します。例では、このテクニックを簡単に紹介します。

オブジェクト (記事、写真、音楽など) へのコメントは、アプリケーションで最も一般的な機能の 1 つです。まず、Comment クラスとそこで使用される「get」メソッドを定義します。

public partial class Comment{    public DateTime CreateTime { get; set; } 
    public string Content { get; set; }
} 
public partial class Comment{    private static List<Comment> s_comments = new List<Comment>
    {        new Comment
        {
            CreateTime = DateTime.Parse("2007-1-1"),
            Content = "今天天气不错"
        },        new Comment
        {
            CreateTime = DateTime.Parse("2007-1-2"),
            Content = "挺风和日丽的"
        },        new Comment
        {
            CreateTime = DateTime.Parse("2007-1-3"),
            Content = "我们下午没有课"
        },        new Comment
        {
            CreateTime = DateTime.Parse("2007-1-1"),
            Content = "这的确挺爽的"
        }
    }; 
    public static List<Comment> GetComments(int pageSize, int pageIndex, out int totalCount)
    {
        totalCount = s_comments.Count; 
        List<Comment> comments = new List<Comment>(pageSize); 
        for (int i = pageSize * (pageIndex - 1);
            i < pageSize * pageIndex && i < s_comments.Count; i++)
        {
            comments.Add(s_comments[i]);
        } 
        return comments;
    }
}
ログイン後にコピー

コメントのリストを表示するには、ユーザー コントロール (ItemComments.aspx) を使用してカプセル化します。当然、ページングも不可欠です:

<asp:Repeater runat="server" ID="rptComments">
    <ItemTemplate>
        时间:<%# (Container.DataItem as Comment).CreateTime.ToString() %><br />
        内容:<%# (Container.DataItem as Comment).Content %> 
    </ItemTemplate>
    <SeparatorTemplate>
        <hr />
    </SeparatorTemplate>    <FooterTemplate>
        <hr />
    </FooterTemplate></asp:Repeater> <% if (this.PageIndex > 1)
   { %>
        <a href="/ViewItem.aspx?page=<%= this.PageIndex - 1 %>" title="上一页">上一页</a> <% } %><% if (this.PageIndex * this.PageSize < this.TotalCount)
   { %>
ログイン後にコピー

および:

public partial class ItemComments : System.Web.UI.UserControl{    protected override void OnPreRender(EventArgs e)
    {        base.OnPreRender(e); 
        this.rptComments.DataSource = Comment.GetComments(this.PageSize,            this.PageIndex, out this.m_totalCount);        this.DataBind();
    } 
    public int PageIndex { get; set; } 
    public int PageSize { get; set; } 
    private int m_totalCount;    public int TotalCount
    {        get
        {            return this.m_totalCount;
        }
    }
}
ログイン後にコピー

次に、ページ (ViewItem.aspx) でこのコンポーネントを使用します:

<p id="comments"><demo:ItemComments ID="itemComments" runat="server" /></p>
ログイン後にコピー

および:

public partial class ViewItem : System.Web.UI.Page{    protected void Page_Load(object sender, EventArgs e)
    {        this.itemComments.PageIndex = this.PageIndex;
    } 
    protected int PageIndex
    {        get
        {            int result = 0;            Int32.TryParse(this.Request.QueryString["page"], out result); 
            return result > 0 ? result : 1;
        }
    }
}
ログイン後にコピー

ViewItem.aspx を開いた後の効果は次のようになります。

時刻: 2007/1/1 0:00:00 内容:今日はいい天気ですね


時間:2007/1/2 0:00:00 内容: とても晴れました


時間: 2007/1/3 0:00:00 内容: 午後は授業がありません


次のページ

このページの機能はとてもシンプルで、コメントを表示するだけです。現在のコメントのページ番号は QueryString のページ項目を使用して指定され、ItemComments.ascx コントロールのプロパティが取得され、ViewItem.aspx に設定されます。 ItemComments コントロールはデータを取得し、独自のプロパティに基づいてバインドします。表示内容については、すべて ascx で定義されます。ページング機能が必要なため、このコメント コントロールには前のページと次のページへのリンクも含まれており、そのリンクのターゲットは ViewItem.aspx ページであり、ページ番号のクエリ文字列のみです。追加した。

機能は完成しているのに、使っているうちに急に違和感を感じたのはなぜですか?ページをめくるとき、またはユーザーがコメントを投稿すると、ページ全体が更新されるからです。これは良くありません。ViewItem ページには他にも表示パーツがいくつかある可能性があり、それらは変更されていないことを知っておく必要があります。また、他のいくつかのパーツもページ分割する必要がある場合は、ページ上の各パーツの現在のページ番号を保持する必要がある場合があるため、開発の複雑さは依然として比較的高くなります。

それでは、AJAX を使ってみましょう。コメントの表示中にユーザーがページをめくったり、コメントを残したりしても、ページ上の他のコンテンツには影響しません。この機能を開発するには、当然サーバー側のサポートが必要になりますが、どうすればよいでしょうか。一般に、常に 2 つのオプションがあります:

  1. サーバーは JSON データを返し、クライアントはレンダリングのために DOM を操作します。

  2. サーバーは HTML コンテンツを直接返し、クライアント上にコンテナーを設定します (たとえば、上記のコメントの ID を持つ p)。

ただし、どのアプローチを採用しても、通常、「プレゼンテーション」ロジックは再度記述されます (最初のプレゼンテーション ロジックは、ItemComments.ascx に記述されます)。最初のアプローチを使用する場合は、DOM を操作してクライアント側でプレゼンテーション ロジックをレンダリングする必要があります。2 番目のアプローチを使用する場合は、サーバー側で文字列の連結を実行する必要があります。どちらのアプローチも DRY 原則に違反します。ItemComments.ascx のプレゼンテーション メソッドを変更すると、それに応じて他の場所も変更する必要があります。また、DOM要素の操作にせよ、文字列のつなぎ合わせにせよ、メンテナンスの手間が大きくなり、開発効率も当然高くありません。

ItemComments コントロールから HTML コンテンツを直接取得できたらどんなに素晴らしいでしょう - それでは、そうしてみましょう。次のコード (GetComments.ashx) を見てください:

public class GetComments : IHttpHandler{    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain"; 
        ViewManager<ItemComments> viewManager = new ViewManager<ItemComments>();        
        ItemComments control = viewManager.LoadViewControl("~/ItemComments.ascx");
 
        control.PageIndex = Int32.Parse(context.Request.QueryString["page"]);
        control.PageSize = 3;
 
        context.Response.Write(viewManager.RenderView(control));
    } 
    public bool IsReusable { ... }
}
ログイン後にコピー

非常に単純なコードですね。オブジェクトを作成し、プロパティを設定して、それを Response.Write 経由で出力するだけです。それは実際には大したことではありません - しかし、鍵は ViewManager クラスにあります。その実装方法を見てみましょう:

public class ViewManager<T> where T : UserControl{    private Page m_pageHolder; 
    public T LoadViewControl(string path)
    {        this.m_pageHolder = new Page();        return (T)this.m_pageHolder.LoadControl(path);
    } 
    public string RenderView(T control)
    {        StringWriter output = new StringWriter(); 
        this.m_pageHolder.Controls.Add(control);        HttpContext.Current.Server.Execute(this.m_pageHolder, output, false); 
        return output.ToString();
    }
}
ログイン後にコピー

ViewManager には LoadViewControl と RenderView の 2 つのメソッドしかありません。 LoadViewControl メソッドの機能は Control インスタンスを作成して返すことであり、RenderView メソッドの機能は HTML を生成することです。この実装のコツは、新しく作成された Page オブジェクトをコントロールを生成するための「コンテナ」として使用することです。最終的には、Page オブジェクトのライフサイクル全体を実際に実行し、結果を出力します。この空の Page オブジェクトは他のコードを生成しないため、取得するのはユーザー コントロールによって生成されたコードです。

しかし、この AJAX 効果を実現するには、2 つのことを行う必要があります。

まず、ItemComments コントロールのページめくりリンクを変更して、クリックされたときに JavaScript 関数を呼び出すようにします。たとえば、「前のページ」のコードは次のようになります。

<a href="/ViewItem.aspx?page=<%= this.PageIndex - 1 %>" title="上一页"    
onclick="return getComments(<%= this.PageIndex - 1 %>);">上一页</a>
ログイン後にコピー

2 番目に、クライアント メソッド getComments を実装します。ここではプロトタイプ フレームワークを使用しました。利点は、非常に簡潔なコードを使用して HTML を置き換える AJAX 効果を実現できることです。

実際、前に述べたように、HTML コード生成に UserControl を使用することは非常に一般的な手法です。特に AJAX アプリケーションの人気が高まっているため、上記の方法を合理的に使用することで、アプリケーションに AJAX 効果を簡単に追加できます。また、多くの場合、ページにコンテンツを表示する必要がない場合でも、UserControl を使用してコンテンツを編集できます。 UserControl を記述する方が、文字列を連結するよりも開発効率と保守性がはるかに高いためです。この方法は実績のある WebForms モデルを実際に使用しているため、実行効率の点でも非常に効率的です。さらに、先ほどの例と同様に、HTML 生成に UserCotrol を使用すると、次のような利点もあります。

  1. ページ レンダリング ロジックは 1 回だけ実装されるため、保守性が向上します。

  2. クライアント側の の href はまだ有効であるため、ページの SEO には影響しません。

実際、WebForms は非常に強力なモデルなので、ASP.NET MVC の View も WebForms エンジンを使用します。上記の例を通じて、UserControl 自体は追加のコンテンツを提供しないため、UserControl を使用して XML データを生成するなど、実際には他の多くのことを行うことができます。

以上がUserControl を使用して HTML を生成するためのヒントの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!