384 Stimmen

Einfügen von Inhalten in bestimmte Abschnitte aus einer Teilansicht ASP.NET MVC 3 mit Razor View Engine

Ich habe diesen Abschnitt in meinem _Layout.cshtml

@RenderSection("Scripts", false)

Ich kann sie leicht aus der Vogelperspektive verwenden:

@section Scripts { 
    @*Stuff comes here*@
}

Was ich kämpfe mit ist, wie man einige Inhalte innerhalb dieses Abschnitts von einer partiellen Ansicht injiziert zu bekommen.

Nehmen wir an, dass dies meine Ansichtsseite ist:

@section Scripts { 

    <script>
        //code comes here
    </script>
}

<div>
    poo bar poo
</div>

<div>
  @Html.Partial("_myPartial")
</div>

Ich muss einige Inhalte in die Scripts Abschnitt von _myPartial Teilansicht.

Wie kann ich das tun?

2voto

Lomak Punkte 71

Sie können diese Erweiterungsmethoden verwenden : (Speichern als PartialWithScript.cs)

namespace System.Web.Mvc.Html
{
    public static class PartialWithScript
    {
        public static void RenderPartialWithScript(this HtmlHelper htmlHelper, string partialViewName)
        {
            if (htmlHelper.ViewBag.ScriptPartials == null)
            {
                htmlHelper.ViewBag.ScriptPartials = new List<string>();
            }

            if (!htmlHelper.ViewBag.ScriptPartials.Contains(partialViewName))
            {
                htmlHelper.ViewBag.ScriptPartials.Add(partialViewName);
            }

            htmlHelper.ViewBag.ScriptPartialHtml = true;
            htmlHelper.RenderPartial(partialViewName);
        }

        public static void RenderPartialScripts(this HtmlHelper htmlHelper)
        {
            if (htmlHelper.ViewBag.ScriptPartials != null)
            {
                htmlHelper.ViewBag.ScriptPartialHtml = false;
                foreach (string partial in htmlHelper.ViewBag.ScriptPartials)
                {
                    htmlHelper.RenderPartial(partial);
                }
            }
        }
    }
}

So verwenden:

Beispiel partiell: (_MyPartial.cshtml) Setzen Sie die html in das if und die js in das else.

@if (ViewBag.ScriptPartialHtml ?? true)
    <p>I has htmls</p>
}
else {
    <script type="text/javascript">
        alert('I has javascripts');
    </script>
}

Fügen Sie in Ihre _Layout.cshtml, oder wo auch immer die Skripte der Teilbereiche gerendert werden sollen, folgendes ein (einmal): Es wird nur das Javascript aller Teilbereiche auf der aktuellen Seite an dieser Stelle gerendert.

@{ Html.RenderPartialScripts(); }

Um Ihren Teilbereich zu verwenden, gehen Sie einfach wie folgt vor: Es wird nur die HTML an dieser Stelle gerendert.

@{Html.RenderPartialWithScript("~/Views/MyController/_MyPartial.cshtml");}

2voto

PaulSanS Punkte 21

Plutos Idee auf eine schönere Art und Weise:

CustomWebViewPage.cs:

    public abstract class CustomWebViewPage<TModel> : WebViewPage<TModel> {

    public IHtmlString PartialWithScripts(string partialViewName, object model) {
        return Html.Partial(partialViewName: partialViewName, model: model, viewData: new ViewDataDictionary { ["view"] = this, ["html"] = Html });
    }

    public void RenderScriptsInBasePage(HelperResult scripts) {
        var parentView = ViewBag.view as WebPageBase;
        var parentHtml = ViewBag.html as HtmlHelper;
        parentView.DefineSection("scripts", () => {
            parentHtml.ViewContext.Writer.Write(scripts.ToHtmlString());
        });
    }
}

Ansichten \web.config :

<pages pageBaseType="Web.Helpers.CustomWebViewPage">

Ansicht:

@PartialWithScripts("_BackendSearchForm")

Teilweise (_BackendSearchForm.cshtml):

@{ RenderScriptsInBasePage(scripts()); }

@helper scripts() {
<script>
    //code will be rendered in a "scripts" section of the Layout page
</script>
}

Layout-Seite:

@RenderSection("scripts", required: false)

1voto

Pluto Punkte 2603

Es gibt eine Möglichkeit, Abschnitte in Teilansichten einzufügen, auch wenn das nicht schön ist. Sie müssen Zugriff auf zwei Variablen der übergeordneten Ansicht haben. Da ein Teil des eigentlichen Zwecks Ihrer partiellen Ansicht darin besteht, diesen Abschnitt zu erstellen, ist es sinnvoll, diese Variablen zu benötigen.

So sieht es aus, wenn Sie einen Abschnitt in die Teilansicht einfügen:

@model KeyValuePair<WebPageBase, HtmlHelper>
@{
    Model.Key.DefineSection("SectionNameGoesHere", () =>
    {
        Model.Value.ViewContext.Writer.Write("Test");
    });
}

Und auf der Seite, die die Teilansicht einfügt...

@Html.Partial(new KeyValuePair<WebPageBase, HtmlHelper>(this, Html))

Sie können diese Technik auch verwenden, um den Inhalt eines Abschnitts in einer beliebigen Klasse programmatisch zu definieren.

Viel Spaß!

1voto

Ich hatte heute dieses Problem. Ich werde einen Workaround hinzufügen, der <script defer> da ich nicht gesehen habe, dass es in den anderen Antworten erwähnt wurde.

//on a JS file somewhere (i.e partial-view-caller.js)
(() => <your partial view script>)();

//in your Partial View
<script src="~/partial-view-caller.js" defer></script>

//you can actually just straight call your partial view script living in an external file - I just prefer having an initialization method :)

Der obige Code ist ein Auszug aus einer Schnellpost Ich habe über diese Frage nachgedacht.

1voto

BlackjacketMack Punkte 5254

Mit Mvc Core können Sie einen aufgeräumten TagHelper erstellen scripts wie unten zu sehen. Dies könnte leicht in eine section Tag, wo Sie ihm auch einen Namen geben (oder der Name wird vom abgeleiteten Typ übernommen). Beachten Sie, dass die Injektion von Abhängigkeiten eingerichtet werden muss für IHttpContextAccessor .

Beim Hinzufügen von Skripten (z. B. in einem Teilbereich)

<scripts>
    <script type="text/javascript">
        //anything here
    </script>
</scripts>

Bei der Ausgabe der Skripte (z. B. in einer Layout-Datei)

<scripts render="true"></scripts>

Code

public class ScriptsTagHelper : TagHelper
    {
        private static readonly object ITEMSKEY = new Object();

        private IDictionary<object, object> _items => _httpContextAccessor?.HttpContext?.Items;

        private IHttpContextAccessor _httpContextAccessor;

        public ScriptsTagHelper(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var attribute = (TagHelperAttribute)null;
            context.AllAttributes.TryGetAttribute("render",out attribute);

            var render = false;

            if(attribute != null)
            {
                render = Convert.ToBoolean(attribute.Value.ToString());
            }

            if (render)
            {
                if (_items.ContainsKey(ITEMSKEY))
                {
                    var scripts = _items[ITEMSKEY] as List<HtmlString>;

                    var content = String.Concat(scripts);

                    output.Content.SetHtmlContent(content);
                }
            }
            else
            {
                List<HtmlString> list = null;

                if (!_items.ContainsKey(ITEMSKEY))
                {
                    list = new List<HtmlString>();
                    _items[ITEMSKEY] = list;
                }

                list = _items[ITEMSKEY] as List<HtmlString>;

                var content = await output.GetChildContentAsync();

                list.Add(new HtmlString(content.GetContent()));
            }
        }
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X