簡體   English   中英

ASP.Net MVC3 - 將剃刀標記作為參數傳遞

[英]ASP.Net MVC3 - Pass razor markup as a parameter

我有一個名為EditableArea的助手,它為用戶提供了一個運行時可編輯的div (通過 JS)。 EditableArea 助手檢查數據庫中是否存在具有指定 ID 的可編輯區域(與 MVC 的Area無關),如果存在,則呈現該區域的 HTML,否則顯示指定為助手參數的默認標記:

@Html.EditableArea(someId, "<p>Click to edit contents</p>")

一切正常,但我想更改它,以便默認標記不是指定為字符串,而是指定為 razor 語法,例如:

@using (Html.EditableArea(someId))
{
    <p>Click to edit contents</p>
}

或者類似的東西,比如@section在 MVC3 中的工作方式。

我怎樣才能做到這一點?

我可以制作一個IDisposable ,它在其Dispose關閉 TagBuilder 等,但使用這種方法仍會呈現標記(我可以清除Dispose()呈現的內容,但代碼塊仍會不必要地運行,我'我想避免)。

是否有其他方法可以將剃刀塊傳遞給助手,實際上可能會或可能不會呈現?

這是我用來呈現 jQuery 模板標記的示例,方法是傳入模板 Id 和模板本身的剃刀樣式語法:

public static MvcHtmlString jQueryTmpl(this HtmlHelper htmlHelper, 
    string templateId, Func<object, HelperResult> template) 
{
    return MvcHtmlString.Create("<script id=\"" + templateId + 
        "\" type=\"x-jquery-tmpl\">" + template.Invoke(null) + "</script>");
}

這將被稱為

@Html.jQueryTmpl("templateId", @<text>any type of valid razor syntax here</text>)

基本上只需使用Func<object, HelperResult>作為您的參數和template.Invoke(null) (如有必要,請使用參數)來呈現它。 顯然,您可以跳過對.Invoke()的調用以避免呈現“默認”標記。

只是為了擴展已接受的答案,因為我花了很長時間來解決類似的問題,這就是出現的問題。 我真正需要的是一個@helper ,它可以接受剃刀文本,因為模板應該包含相當多的代碼。 我玩了很長時間,試圖使用我在網上找到的@helper item(Func<object, HelperResult> input)類型的多個版本,但沒有成功。 因此,我采用了如下方法:

namespace project.MvcHtmlHelpers
{
    public static class HelperExtensions
    {
        public static MvcHtmlString RazorToMvcString(this HtmlHelper htmlHelper, Func<object, HelperResult> template)
        {
            return MvcHtmlString.Create(template.Invoke(null).ToString());
        }
    }
}

@project.MvcHtmlHelpers    
@helper item(other input, MvcHtmlString content)
    {
        <div class="item">
            ...other stuff... 
            <div class="content">
                @content
            </div>
        </div>
    }

並通過這個使用

@item(other input, @Html.RazorToMvcString(@<text>this is a test</text>))

現在我可以將輔助模板用於 Razor 輸入,但我也可以放入部分視圖,這在某些時候很方便。 由於我不是專家,可能有更好的選擇,但這對我來說似乎是一種靈活的方法。

如果您想知道這是如何在 asp.net core 3.1 中做到的

@{
    void TemplateFunc(Func<object, IHtmlContent> template)
    {
        <div>@template(null)</div>
    }
}

然后在標記中,您可以將其用作

<div>
@{TemplateFunc(@<div>123</div>);}
</div>

更進一步,可以將標記直接傳遞給助手,而無需擴展方法。

@helper HelperWithChild(Func<object, HelperResult> renderChild)
{
    <div class="wrapper">
        @renderChild(this)
    </div>
}

@HelperWithChild(@<h1>Hello</h1>)

對於多行標記<text>也是必需的:

@HelperWithChild(@<text>
    @AnotherHelper()

    <h1>
        With more markup
    </h1>
</text>)

@helper AnotherHelper()
{
    <p>
        Another helper
    </p>
}

雖然我不確定this將如何與Model一起發揮作用 - 我的助手只使用他們的參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM