程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> ASP編程 >> ASP技巧 >> 使用自定義ViewHelper來簡化Asp.net MVC view的開發------part4

使用自定義ViewHelper來簡化Asp.net MVC view的開發------part4

編輯:ASP技巧

 接上篇,我們下面通過HtmlFiledSet helper來展示何時使用EndVIEw():

    如果你用ASP.net已經有一段時間了,那使用Html.BeginForm helper來創建Html form標簽的方式會讓你覺得有點怪.當你創建一個新的ASP.Net mvc項目後,在VIEw裡的ChangePassWord.ASPx會默認被創建,這個頁面使用了Html.BeginForm helper,下面是使用這個helper的代碼段:

<% using (Html.BeginForm()) { %>
    <div>
        <fIEldset>
            <legend>Account Information</legend>
            <p>
                <label for="currentPassword">Current passWord:</label>
                <%= Html.Password("currentPassWord") %>
                <%= Html.ValidationMessage("currentPassWord") %>
            </p>
            <p>
                <label for="newPassword">New passWord:</label>
                <%= Html.Password("newPassWord") %>
                <%= Html.ValidationMessage("newPassWord") %>
            </p>
            <p>                 <label for="confirmPassword">Confirm new passWord:</label>
                <%= Html.Password("confirmPassWord") %>
                <%= Html.ValidationMessage("confirmPassWord") %>
            </p>
            <p>
                <input type="submit" value="Change PassWord" />
            </p>
        </fIEldset>
    </div>
<% } %>
上面代碼中你會發現Html.BeginForm的使用和<%=Html.Password(“currentPassWord”) %>的使用不盡相同,也就是Html.BeginForm在using語句中被調用,這點很有意思,讓我先來看看上面代碼段生成後的Html,如下:

<form 
  action="/Account/LogOn?ReturnUrl=%2fAccount%2fChangePassWord" 
  method="post">
  <div>
    <fIEldset>
      <legend>Account Information</legend>
      <p>
        <label for="username">Username:</label>
        <input id="username" name="username" type="text" value="" />  
      </p>
      <p>
        <label for="password">PassWord:</label>
        <input id="password" name="password" type="passWord" />  
      </p>
      <p>
        <input id="rememberMe" name="rememberMe" type="checkbox" value="true" />
        <input name="rememberMe" type="hidden" value="false" />
        <label class="inline" for="rememberMe">Remember me?</label>
      </p>
      <p>
        <input type="submit" value="Log On" />
      </p>
    </fIEldset>
  </div>
</form> 比較<%= Html.Password("currentPassword") %> 語句和Html.BeginForm所生成的HTML代碼你會發現password那段僅僅僅僅將調用passWord擴展方法變成對應的Html,而BeginForm調用HTML擴展方法來注入form的開始標簽,<form…>,和using語句結束時(“}”)注入標簽<./form>.這種方式十分方便,因為我們可以一方面使用vIEw helper創建合適的form標簽,另一方面在form標簽內插入任何我們想插入的html.這種方法的工作原理是當你調用Html.BeginForm方法並返回MvcForm類型的對象,這個對象在using語句中所以當對象被回收(譯者按:也就是Dispose)的時候,也就是執行到結尾的”<% } %>”時,關閉標簽</form>將會被寫入到VIEw中.下面是Dispose方法的實現:

public void Dispose() {
    Dispose(true /* disposing */);
    GC.SupPRessFinalize(this);
}

protected virtual void Dispose(bool disposing) {
    if (!_disposed) {
        _disposed = true;
        _httpResponse.Write("</form>");
    }

我們用相似的方法來實現HtmlFIEldSet:

從這篇文章附帶的代碼中有一個”DetailsClassic.ASPx”頁面中,一些字段包含於fIEldset元素中,具體代碼如下:

<fieldset class="details-fIEld-group" name="Details">
  <legend>Details</legend>
  <ol>
    <li>
      <label for="FirstName">FirstName</label>
      <span id="FirstName">
        <%= Html.Encode(Model.FirstName) %></span> 
    </li>
    <li>
      <label for="LastName">LastName</label>
      <span id="LastName"><%= Html.Encode(Model.LastName) %></span>
    </li>
    <li>
      <label for="Email">Email</label>
      <span id="Email"><%= Html.Encode(Model.Email) %></span>
    </li>
    <li>
      <label for="Phone">Phone</label>
      <span id="Phone"><%= Html.Encode(Model.Phone) %></span>
    </li>
    <li>
      <label for="Gender">Gender</label>
      <span id="Gender"><%= Html.Encode(Model.Gender) %></span>
    </li>
  </ol>
</fieldset> 如果能用一個vIEw helper來創建下面所有的Html標簽,那會惬意很多:

fIEldset的開始標記
legend標簽
ol的開始標簽
ol的結束標簽
fIEldset的結束標簽
如果能用view helper來處理這些,那上面那段代碼無疑會簡單很多,尤其再加上使用Html.Text標簽來代替上面的text域。讓我們開始做到這一點,首先創建一個實現IViewObject接口的類,命名為HtmlFIEldSet類並繼承與AbstractHtmlVIEwObject,整個類的代碼附下:

public class HtmlFIEldset : AbstractHtmlVIEwObject
{
    private readonly string mTitle;

    public HtmlFIEldset(
        VIEwRequestContext requestContext, string name, 
        string title, object attributes)
        : base(requestContext, name)
    {
        mTitle = title;
        Attributes = attributes;
    }

    private TagBuilder FIEldsetTag { get; set; }

    private TagBuilder OlTag { get; set; }

    public override void StartVIEw()
    {
        HttpResponseBase httpResponse = RequestContext.HttpResponse;

        FieldsetTag = new TagBuilder("fIEldset");

        // apply any Attributes passed in
        if (Attributes != null)
        {
            FIEldsetTag.MergeAttributes(new RouteValueDictionary(Attributes));
        } 
        // The Name property should override any passed into the Attributes
        FIEldsetTag.MergeAttribute("name", Name, true);

        httpResponse.Write(FIEldsetTag.ToString(TagRenderMode.StartTag));

        if (!string.IsNullOrEmpty(mTitle))
        {
            TagBuilder legendTag = new TagBuilder("legend");
            legendTag.SetInnerText(mTitle);
            httpResponse.Write(legendTag.ToString(TagRenderMode.Normal));
        }

        OlTag = new TagBuilder("ol");
        httpResponse.Write(OlTag.ToString(TagRenderMode.StartTag));
    }

    public override void EndVIEw()
    {
        HttpResponseBase httpResponse = RequestContext.HttpResponse;

        httpResponse.Write(OlTag.ToString(TagRenderMode.EndTag));
        httpResponse.Write(FIEldsetTag.ToString(TagRenderMode.EndTag));
    }
}
這個類的實現和其它的view對象沒什麼不同,除了EndView方法,在這裡我們需要EndView方法來生成必須的結束標記。當然我們也可以使用EndVIEw來生成任何需要的Html,在這裡我們僅是用它生成結束標記。

-------------------------------------------

待續…

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved