简体   繁体   中英

MVC 4 - How to pass a template to an html helper method

I need to have all my scripts at the bottom of the page, problem is when I have a Partial View I cannot use the "RenderSection" approach. Found a great example of how to add a HtmlHelper extension which takes the name of a script file, loads into a stack, then another helper renders that out on the base layout: Razor section inclusions from partial view

That's great - but I don't want to have to create an entire JS file for a little chunk of script, or maybe even HTML, that I want to drop in. And I don't want to pass it all as a string, I want the nice formatting and intellisense, so I want to use a template ie:

@{Html.AddScript("test", @<text>
<script type="text/javascript">
    function RefreshPreview() {
        $('#AutoReplyHtml_Preview').html(
            $('#htmlTemplate').html()
                .replace('@@MESSAGE_TITLE@@', $('#AutoReplySubject').val())
                .replace('@@PRE_HEADER@@', $('#AutoReplyPreHeader').val())
                .replace('@@MESSAGE_BODY@@', $('#AutoReplyHtml').val())
        );

        $('#AutoReplyPlainText_Preview').html(
            $('#plainTextTemplate').html()
                .replace('@@MESSAGE_BODY@@', $('#AutoReplyPlainText').val())
        );
    }

    $(document).ready(function() {
        RefreshPreview();
    });
</script>
</text>);}

Problem is - how to I get the value of the template into my method, I have this code which complies, but no clue how to get the data out of the "code" parameter:

    public static string AddScript(this HtmlHelper htmlHelper, string title, Func<object, object> code) {
    var ctx = htmlHelper.ViewContext.HttpContext;
    Dictionary<string, string> scripts = ctx.Items["HtmlHelper.AddScript"] as Dictionary<string, string>;
    if (scripts == null) {
        scripts = new Dictionary<string, string>();
        ctx.Items.Add("HtmlHelper.AddScript", scripts);
    }

    scripts.Add(title, code.ToString()); //Doens't work!

    return string.Empty;
}

How do I need to tweak the delegate parameter to get the value inside the template??

The helper architecture is designed so that it can accomodate scenarios where you are providing a template that will operate, for example, on each item in a list. In such a scenario, you'd of course want to be able to pass it the "current" item when iterating through the list.

However, in other scenarios (such as yours), there is no current item . Yet, as you've discovered, you still have to declare a delegate as a parameter to your method that defines a method that consumes one parameter. That's ok -- since you're not consuming that argument in your helper (you don't make use of the somewhat magical item parameter in your template) you can just pass it null in your implementation. Preferably, declare your parameter as a Func<object, IHtmlString> rather than a Func<object, object> , but regardless, just invoke code(null).ToString() to get the HTML-encoded string you need to render.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM