[Asp .Net MVC]使用Razor自定functions (與 HtmlHelper 比較)

functions => 函數 (在前端寫c#語法) = 你原本在後端怎麼寫c# 在前端就怎麼寫

 

上一篇我們分享了如何使用HtmlHelper來做一些運算產生Html Tag

 

再次考量這個案例

 

考量下面多種寫法

可知

HtmlHelper

=>讓我們用類似寫C#的方式動態組出Html Tag => 輸出結果必定是Html元素 例:div、input、button......

functions

=> 就是寫在前端Razor的C#語法 => 輸出結果較彈性

 

看起來好像HtmlHelper可以做的事情比較多

畢竟透過Razor的幫助 可以在編譯期自動幫我們檢查我們在組合Html元素是否有打錯字

例如: Tag是否有相對應的結束標籤、css屬性是否打錯字等等

 

但考量這個例子

假設算出BMI值的分母值 這個函式還會被其他函式呼叫、或是有其他HtmlHelper要拿來做不同Html標籤呈現時 (紅色、藍色、綠色......)

此時我們需要提出這段程式碼

但HtmlHelper本身並沒有傳回值 他其實就是一段Html語法

所以這時後便只有functions辦得到了

 

考量View裡的程式碼

//使用HtmlHelper => Html支援的都能使用
@MyHtmlHelper.GetBmiByHtmlHelper(item.HEIGHT, item.WEIGHT) 
//使用functions => 單純的後端c#函式,無頁面客製邏輯
@MyHtmlHelper.GetBmiByFunc(item.HEIGHT, item.WEIGHT)
//使用functions又想要文字變色 => 自己組script (有打錯字風險)
@(new HtmlString(MyHtmlHelper.GetBmiByFunc2(item.HEIGHT, item.WEIGHT)))

 

其中可以注意這段語法

@(new HtmlString("一段html語法"))

例如: @(new HtmlString("<table><tr><td>你好</td></tr></table>"))

能指定Razor將字串解析為html script (即頁面上會秀出一個表格) 而不是一段<table>.....的文字

 

完整程式碼如下

@*HtmlHelper的目的是要幫我們產生Html Tag 例如:Label、Div、Button...*@
@*故輸出的結果必定是Tag*@
@helper GetBmiByHtmlHelper(double height, double weight)
{

var value = weight / GetDenominator(height);

    <span style="color:red">@value</span> @*如果打錯html、css,Razor會幫你檢查*@
}

@functions{
    /// <summary>
    /// 當你想從HtmlHelper裡提出某些共用的邏輯時...(還會被其他HtmlHelper使用)
    /// </summary>
    private static double GetDenominator(double height)
    {
        return Math.Pow((height / 100), 2);
    }

    /// <summary>
    /// 如同你在寫後端 C# 程式
    /// </summary>
    public static double GetBmiByFunc(double height, double weight)
    {
        return weight / Math.Pow((height / 100), 2);
    }

    /// <summary>
    /// 比較與 HtmlHelper 間的差異,為了達成格式=紅色字,這裡必須用字串方式串接 (缺點: 容易打錯字) 
    /// </summary>
    public static string GetBmiByFunc2(double height, double weight)
    {
        var result = weight / Math.Pow((height / 100), 2);

        return "<span style='color: red'>" + result+ "</span>";
    }
}
@model IEnumerable<Repository.Models.MySampleTable>
@{
    ViewBag.Title = "Hello World!";
}
<h2>@ViewBag.Title</h2>

<p>
    <br />
    <table class="table">
        <tr>
            <th>ID</th>
            <th>NAME</th>
            <th>BIRTHDAY</th>
            <th>HEIGHT</th>
            <th>WEIGHT</th>
            <th>BMI (HtmlHelper)</th>
            <th>BMI (functions)</th>
            <th>BMI (functions-raw)</th>
        </tr>
        @foreach (var item in Model)
        {
            <tr>
                <td>@item.ID</td>
                <td>@item.NAME</td>
                <td>@item.BIRTHDAY</td>
                <td>@item.HEIGHT</td>
                <td>@item.WEIGHT</td>
                <td>@MyHtmlHelper.GetBmiByHtmlHelper(item.HEIGHT, item.WEIGHT)</td>
                <td>@MyHtmlHelper.GetBmiByFunc(item.HEIGHT, item.WEIGHT)</td>
                <td>@(new HtmlString(MyHtmlHelper.GetBmiByFunc2(item.HEIGHT, item.WEIGHT)))</td>
           </tr>
        }
    </table>
</p>