Injection de contenu dans des sections spécifiques à partir d'une vue partielle ASP.NET MVC 3 avec le moteur Razor View

j'ai cette section définie dans mon _Layout.cshtml

@RenderSection("Scripts", false)

je peux facilement l'utiliser d'un point de vue:

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

ce qui me pose problème, c'est comment obtenir du contenu injecté à l'intérieur de cette section À partir d'une vue partielle.

supposons que ce soit ma page de vue:

@section Scripts { 

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

<div>
    poo bar poo
</div>

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

je dois injecter du contenu à l'intérieur de la section Scripts de _myPartial vue partielle.

Comment faire?

284
demandé sur niico 2011-09-26 18:12:22

22 réponses

Les Sections

ne fonctionnent pas en vue partielle et c'est par conception. Vous pouvez utiliser certains helpers personnalisés pour obtenir un comportement similaire, mais honnêtement, c'est la responsabilité de la vue d'inclure les scripts nécessaires, pas la responsabilité du partial. Je recommande l'utilisation de la section @scripts de la vue principale pour faire cela et ne pas avoir les partiels se soucient des scripts.

207
répondu Darin Dimitrov 2017-05-23 12:26:38

c'est une question très populaire, donc je vais poster ma solution.

J'ai eu le même problème et bien qu'il ne soit pas idéal, je pense qu'il fonctionne en fait assez bien et ne rend pas la partie dépendante sur la vue.

Mon scénario était qu'une action était accessible par elle - même mais pouvait aussi être intégrée dans une vue-une carte google.

Dans mon _layout j'ai:

@RenderSection("body_scripts", false)

dans mon index vue que j'ai:

@Html.Partial("Clients")
@section body_scripts
{
    @Html.Partial("Clients_Scripts")
}

Dans mon clients vue que j'ai (toute la carte et assoc. html):

@section body_scripts
{
    @Html.Partial("Clients_Scripts")
}

Mon Clients_Scripts affichage contient le code javascript pour être rendu sur la page

de cette façon mon script est isolé et peut être rendu dans la page si nécessaire, avec l'étiquette body_scripts étant seulement rendu sur la première occurrence que le moteur de vue de rasoir le trouve.

Cela me permet d'avoir tout séparé - c'est une solution qui fonctionne assez bien pour moi, d'autres peuvent avoir des problèmes avec elle, mais il ne patch le trou "by design".

74
répondu dan richardson 2014-10-27 09:05:53

D'après les solutions de ce fil de discussion , j'ai trouvé la solution suivante, probablement trop compliquée, qui vous permet de retarder le rendu de n'importe quel html (scripts aussi) dans un bloc d'utilisation.

USAGE

créer la "section"

  1. scénario typique: dans une vue partielle, n'inclure le bloc qu'une seule fois, peu importe le nombre de fois où la vue partielle est répété dans la page:

    @using (Html.Delayed(isOnlyOne: "some unique name for this section")) {
        <script>
            someInlineScript();
        </script>
    }
    
  2. Dans une vue partielle, inclure le bloc pour chaque temps partiel est utilisé:

    @using (Html.Delayed()) {
        <b>show me multiple times, @Model.Whatever</b>
    }
    
  3. dans une vue partielle, n'inclure le bloc qu'une seule fois, peu importe le nombre de fois où le partiel est répété, mais plus tard le rendre spécifiquement par son nom when-i-call-you :

    @using (Html.Delayed("when-i-call-you", isOnlyOne: "different unique name")) {
        <b>show me once by name</b>
        <span>@Model.First().Value</span>
    }
    

rend les" sections

(i.e. afficher la section retardée dans une vue mère)

@Html.RenderDelayed(); // writes unnamed sections (#1 and #2, excluding #3)
@Html.RenderDelayed("when-i-call-you", false); // writes the specified block, and ignore the `isOnlyOne` setting so we can dump it again
@Html.RenderDelayed("when-i-call-you"); // render the specified block by name
@Html.RenderDelayed("when-i-call-you"); // since it was "popped" in the last call, won't render anything due to `isOnlyOne` provided in `Html.Delayed`

CODE

public static class HtmlRenderExtensions {

    /// <summary>
    /// Delegate script/resource/etc injection until the end of the page
    /// <para>@via https://stackoverflow.com/a/14127332/1037948 and http://jadnb.wordpress.com/2011/02/16/rendering-scripts-from-partial-views-at-the-end-in-mvc/ </para>
    /// </summary>
    private class DelayedInjectionBlock : IDisposable {
        /// <summary>
        /// Unique internal storage key
        /// </summary>
        private const string CACHE_KEY = "DCCF8C78-2E36-4567-B0CF-FE052ACCE309"; // "DelayedInjectionBlocks";

        /// <summary>
        /// Internal storage identifier for remembering unique/isOnlyOne items
        /// </summary>
        private const string UNIQUE_IDENTIFIER_KEY = CACHE_KEY;

        /// <summary>
        /// What to use as internal storage identifier if no identifier provided (since we can't use null as key)
        /// </summary>
        private const string EMPTY_IDENTIFIER = "";

        /// <summary>
        /// Retrieve a context-aware list of cached output delegates from the given helper; uses the helper's context rather than singleton HttpContext.Current.Items
        /// </summary>
        /// <param name="helper">the helper from which we use the context</param>
        /// <param name="identifier">optional unique sub-identifier for a given injection block</param>
        /// <returns>list of delayed-execution callbacks to render internal content</returns>
        public static Queue<string> GetQueue(HtmlHelper helper, string identifier = null) {
            return _GetOrSet(helper, new Queue<string>(), identifier ?? EMPTY_IDENTIFIER);
        }

        /// <summary>
        /// Retrieve a context-aware list of cached output delegates from the given helper; uses the helper's context rather than singleton HttpContext.Current.Items
        /// </summary>
        /// <param name="helper">the helper from which we use the context</param>
        /// <param name="defaultValue">the default value to return if the cached item isn't found or isn't the expected type; can also be used to set with an arbitrary value</param>
        /// <param name="identifier">optional unique sub-identifier for a given injection block</param>
        /// <returns>list of delayed-execution callbacks to render internal content</returns>
        private static T _GetOrSet<T>(HtmlHelper helper, T defaultValue, string identifier = EMPTY_IDENTIFIER) where T : class {
            var storage = GetStorage(helper);

            // return the stored item, or set it if it does not exist
            return (T) (storage.ContainsKey(identifier) ? storage[identifier] : (storage[identifier] = defaultValue));
        }

        /// <summary>
        /// Get the storage, but if it doesn't exist or isn't the expected type, then create a new "bucket"
        /// </summary>
        /// <param name="helper"></param>
        /// <returns></returns>
        public static Dictionary<string, object> GetStorage(HtmlHelper helper) {
            var storage = helper.ViewContext.HttpContext.Items[CACHE_KEY] as Dictionary<string, object>;
            if (storage == null) helper.ViewContext.HttpContext.Items[CACHE_KEY] = (storage = new Dictionary<string, object>());
            return storage;
        }


        private readonly HtmlHelper helper;
        private readonly string identifier;
        private readonly string isOnlyOne;

        /// <summary>
        /// Create a new using block from the given helper (used for trapping appropriate context)
        /// </summary>
        /// <param name="helper">the helper from which we use the context</param>
        /// <param name="identifier">optional unique identifier to specify one or many injection blocks</param>
        /// <param name="isOnlyOne">extra identifier used to ensure that this item is only added once; if provided, content should only appear once in the page (i.e. only the first block called for this identifier is used)</param>
        public DelayedInjectionBlock(HtmlHelper helper, string identifier = null, string isOnlyOne = null) {
            this.helper = helper;

            // start a new writing context
            ((WebViewPage)this.helper.ViewDataContainer).OutputStack.Push(new StringWriter());

            this.identifier = identifier ?? EMPTY_IDENTIFIER;
            this.isOnlyOne = isOnlyOne;
        }

        /// <summary>
        /// Append the internal content to the context's cached list of output delegates
        /// </summary>
        public void Dispose() {
            // render the internal content of the injection block helper
            // make sure to pop from the stack rather than just render from the Writer
            // so it will remove it from regular rendering
            var content = ((WebViewPage)this.helper.ViewDataContainer).OutputStack;
            var renderedContent = content.Count == 0 ? string.Empty : content.Pop().ToString();
            // if we only want one, remove the existing
            var queue = GetQueue(this.helper, this.identifier);

            // get the index of the existing item from the alternate storage
            var existingIdentifiers = _GetOrSet(this.helper, new Dictionary<string, int>(), UNIQUE_IDENTIFIER_KEY);

            // only save the result if this isn't meant to be unique, or
            // if it's supposed to be unique and we haven't encountered this identifier before
            if( null == this.isOnlyOne || !existingIdentifiers.ContainsKey(this.isOnlyOne) ) {
                // remove the new writing context we created for this block
                // and save the output to the queue for later
                queue.Enqueue(renderedContent);

                // only remember this if supposed to
                if(null != this.isOnlyOne) existingIdentifiers[this.isOnlyOne] = queue.Count; // save the index, so we could remove it directly (if we want to use the last instance of the block rather than the first)
            }
        }
    }


    /// <summary>
    /// <para>Start a delayed-execution block of output -- this will be rendered/printed on the next call to <see cref="RenderDelayed"/>.</para>
    /// <para>
    /// <example>
    /// Print once in "default block" (usually rendered at end via <code>@Html.RenderDelayed()</code>).  Code:
    /// <code>
    /// @using (Html.Delayed()) {
    ///     <b>show at later</b>
    ///     <span>@Model.Name</span>
    ///     etc
    /// }
    /// </code>
    /// </example>
    /// </para>
    /// <para>
    /// <example>
    /// Print once (i.e. if within a looped partial), using identified block via <code>@Html.RenderDelayed("one-time")</code>.  Code:
    /// <code>
    /// @using (Html.Delayed("one-time", isOnlyOne: "one-time")) {
    ///     <b>show me once</b>
    ///     <span>@Model.First().Value</span>
    /// }
    /// </code>
    /// </example>
    /// </para>
    /// </summary>
    /// <param name="helper">the helper from which we use the context</param>
    /// <param name="injectionBlockId">optional unique identifier to specify one or many injection blocks</param>
    /// <param name="isOnlyOne">extra identifier used to ensure that this item is only added once; if provided, content should only appear once in the page (i.e. only the first block called for this identifier is used)</param>
    /// <returns>using block to wrap delayed output</returns>
    public static IDisposable Delayed(this HtmlHelper helper, string injectionBlockId = null, string isOnlyOne = null) {
        return new DelayedInjectionBlock(helper, injectionBlockId, isOnlyOne);
    }

    /// <summary>
    /// Render all queued output blocks injected via <see cref="Delayed"/>.
    /// <para>
    /// <example>
    /// Print all delayed blocks using default identifier (i.e. not provided)
    /// <code>
    /// @using (Html.Delayed()) {
    ///     <b>show me later</b>
    ///     <span>@Model.Name</span>
    ///     etc
    /// }
    /// </code>
    /// -- then later --
    /// <code>
    /// @using (Html.Delayed()) {
    ///     <b>more for later</b>
    ///     etc
    /// }
    /// </code>
    /// -- then later --
    /// <code>
    /// @Html.RenderDelayed() // will print both delayed blocks
    /// </code>
    /// </example>
    /// </para>
    /// <para>
    /// <example>
    /// Allow multiple repetitions of rendered blocks, using same <code>@Html.Delayed()...</code> as before.  Code:
    /// <code>
    /// @Html.RenderDelayed(removeAfterRendering: false); /* will print */
    /// @Html.RenderDelayed() /* will print again because not removed before */
    /// </code>
    /// </example>
    /// </para>

    /// </summary>
    /// <param name="helper">the helper from which we use the context</param>
    /// <param name="injectionBlockId">optional unique identifier to specify one or many injection blocks</param>
    /// <param name="removeAfterRendering">only render this once</param>
    /// <returns>rendered output content</returns>
    public static MvcHtmlString RenderDelayed(this HtmlHelper helper, string injectionBlockId = null, bool removeAfterRendering = true) {
        var stack = DelayedInjectionBlock.GetQueue(helper, injectionBlockId);

        if( removeAfterRendering ) {
            var sb = new StringBuilder(
#if DEBUG
                string.Format("<!-- delayed-block: {0} -->", injectionBlockId)
#endif
                );
            // .count faster than .any
            while (stack.Count > 0) {
                sb.AppendLine(stack.Dequeue());
            }
            return MvcHtmlString.Create(sb.ToString());
        } 

        return MvcHtmlString.Create(
#if DEBUG
                string.Format("<!-- delayed-block: {0} -->", injectionBlockId) + 
#endif
            string.Join(Environment.NewLine, stack));
    }


}
33
répondu drzaus 2017-05-23 10:31:37

j'ai eu ce problème et j'ai utilisé cette technique .

c'est la meilleure solution que j'ai trouvé qui est très flexible.

Aussi s'il vous plaît voter ici pour ajouter le support pour cumulatif de déclaration de la section

14
répondu iBoy 2015-11-20 09:50:27

suivant le principe discret , il n'est pas tout à fait nécessaire pour" _myPartial " d'injecter du contenu directement dans la section scripts. Vous pouvez ajouter ces scripts de vue partielle dans un fichier séparé .js et les référencer dans la section @scripts à partir de la vue parent.

8
répondu archil 2011-09-26 14:21:32

Si vous avez un besoin légitime d'exécuter certains js à partir d'un partial , voici comment vous pourriez le faire, jQuery est nécessaire:

<script type="text/javascript">        
    function scriptToExecute()
    {
        //The script you want to execute when page is ready.           
    }

    function runWhenReady()
    {
        if (window.$)
            scriptToExecute();                                   
        else
            setTimeout(runWhenReady, 100);
    }
    runWhenReady();
</script>
7
répondu Serj Sagan 2015-11-20 17:16:47

il y a un défaut fondamental dans la façon dont nous pensons web, en particulier lorsque nous utilisons MVC. Le défaut est que JavaScript est en quelque sorte la responsabilité de la vue. Une vue est une vue, JavaScript (comportemental ou autre) est JavaScript. Dans le modèle MVVM de Silverlight et de la WPF, nous sommes confrontés à "view first" ou "model first". Dans MVC nous devrions toujours essayer de raisonner du point de vue du modèle et JavaScript fait partie de ce modèle à bien des égards.

je suggérerais d'utiliser le AMD (moi, j'aime RequireJS ). Séparez votre JavaScript en modules, définissez votre fonctionnalité et connectez-vous à votre html à partir de JavaScript au lieu de compter sur une vue pour charger le JavaScript. Cela nettoiera votre code, séparera vos préoccupations et rendra la vie plus facile d'un seul coup.

4
répondu Mr. Baudin 2013-06-18 09:00:54

La première solution que je pense, est d'utiliser ViewBag pour stocker les valeurs qui doivent être rendus.

Onestatly Je n'ai jamais essayé si ce travail d'un point de vue partiel, mais il devrait imo.

2
répondu Iridio 2011-09-26 14:18:00

il y a un moyen d'insérer des sections dans des vues partielles, bien que ce ne soit pas joli. Vous devez avoir accès à deux variables du point de vue des parents. Comme une partie du but de votre vue partielle est de créer cette section, il est logique d'exiger ces variables.

voici à quoi ressemble l'insertion d'une section dans la vue partielle:

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

et dans la page insérant la vue partielle...

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

You pouvez également utiliser cette technique pour définir le contenu d'une section par programme dans n'importe quelle classe.

Profitez-en!

1
répondu Pluto 2014-08-29 15:47:33

vous pouvez utiliser ces méthodes D'Extension : (enregistrer en 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);
                }
            }
        }
    }
}

utiliser comme ceci:

exemple partiel: (_MyPartial.cshtml) Mettez le html dans le Fi, et le js dans l'autre.

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

dans votre _Layout.cshtml, ou partout où vous voulez que les scripts des partiels soient rendus, mettez ce qui suit (une fois): javascript de tous les partiels sur la page courante à cet endroit.

@{ Html.RenderPartialScripts(); }

alors pour utiliser votre partiel, faites simplement ceci: il ne rendra que le html à cet endroit.

@{Html.RenderPartialWithScript("~/Views/MyController/_MyPartial.cshtml");}
1
répondu Lomak 2016-04-25 12:40:57

cela a fonctionné pour moi me permettant de co-localiser javascript et html pour une vue partielle dans le même fichier. Aide avec le processus de pensée pour voir html et la partie liée dans le même fichier de vue partielle.


en vue qui utilise une vue partielle appelée " _MyPartialView.CSHTML "

<div>
    @Html.Partial("_MyPartialView",< model for partial view>,
            new ViewDataDictionary { { "Region", "HTMLSection" } } })
</div>

@section scripts{

    @Html.Partial("_MyPartialView",<model for partial view>, 
                  new ViewDataDictionary { { "Region", "ScriptSection" } })

 }

En Vue Partielle fichier

@model SomeType

@{
    var region = ViewData["Region"] as string;
}

@if (region == "HTMLSection")
{


}

@if (region == "ScriptSection")
{
        <script type="text/javascript">
    </script">
}
1
répondu purvin 2017-01-12 13:18:32

vous ne pouvez pas avoir besoin d'utiliser des sections en vue partielle.

incluez dans votre vue partielle. Il exécute la fonction après jQuery chargé. Vous pouvez modifier la clause de condition pour votre code.

<script type="text/javascript">    
var time = setInterval(function () {
    if (window.jQuery != undefined) {
        window.clearInterval(time);

        //Begin
        $(document).ready(function () {
           //....
        });
        //End
    };
}, 10); </script>

Julio Spader

0
répondu Julio Spader 2014-05-30 17:29:11

j'ai résolu cette voie complètement différente (parce que j'étais pressé et que je ne voulais pas mettre en place un nouveau Helper HTML):

j'ai enveloppé ma vue partielle dans une grande déclaration if-else:

@if ((bool)ViewData["ShouldRenderScripts"] == true){
// Scripts
}else{
// Html
}

ensuite, j'ai appelé le partiel deux fois avec une ViewData personnalisée:

@Html.Partial("MyPartialView", Model, 
    new ViewDataDictionary { { "ShouldRenderScripts", false } })

@section scripts{
    @Html.Partial("MyPartialView", Model, 
        new ViewDataDictionary { { "ShouldRenderScripts", true } })
}
0
répondu Rick Love 2015-01-28 20:16:46

j'ai eu un problème similaire, où j'ai eu une page maître comme suit:

@section Scripts {
<script>
    $(document).ready(function () {
        ...
    });
</script>
}

...

@Html.Partial("_Charts", Model)

mais la vue partielle dépendait d'un certain JavaScript dans la section Scripts. Je l'ai résolu en encodant la vue partielle comme JSON, en la chargeant dans une variable JavaScript et en utilisant ceci pour peupler un div, donc:

@{
    var partial = Html.Raw(Json.Encode(new { html = Html.Partial("_Charts", Model).ToString() }));
}

@section Scripts {
<script>
    $(document).ready(function () {
        ...
        var partial = @partial;
        $('#partial').html(partial.html);
    });
</script>
}

<div id="partial"></div>
0
répondu John M 2016-06-30 08:43:01

au choix, vous pouvez utiliser votre répertoire/index.cshtml comme page principale, puis ajouter des scripts de section. Puis, dans votre mise en page vous avez:

@RenderSection("scripts", required: false) 

et votre index.cshtml:

@section scripts{
     @Scripts.Render("~/Scripts/file.js")
}

et ça marchera sur tous vos points de vue partiels. Il travaille pour moi

0
répondu RogerEdward 2016-12-06 14:18:02

Pluton à l'idée dans une jolie manière:

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());
        });
    }
}

Vues\web.config:

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

:

@PartialWithScripts("_BackendSearchForm")

Partial (_BackendSearchForm.cshtml):

@{ RenderScriptsInBasePage(scripts()); }

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

mise en page:

@RenderSection("scripts", required: false)
0
répondu PaulSanS 2016-12-23 07:32:25

en utilisant MVC Core vous pouvez créer un Helper scripts comme vu ci-dessous. Cela pourrait facilement être transformé en une étiquette section où vous lui donnez un nom aussi bien (ou le nom est pris du type dérivé). Notez que l'injection de dépendances doit être configurée pour IHttpContextAccessor .

lors de l'ajout de scripts (p.ex. dans une partie)

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

lors de la sortie des scripts (par exemple dans un fichier de mise en page))

<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()));
            }
        }
    }
0
répondu BlackjacketMack 2017-12-14 17:14:22

je viens d'ajouter ce code sur ma vue partielle et résolu le problème, mais pas très propre, il fonctionne. Vous devez vous assurer que les Id des objets que vous rendez.

$(document.)ready(function () { $("#Profile_ProfileID").selectmenu({ icons: { bouton: 'ui-icon-circle-flèche-s' } }); $("#TitleID_FK").selectmenu({ icons: { bouton: 'ui-icon-circle-flèche-s' } }); $("#CityID_FK").selectmenu({ icons: { bouton: 'ui-icon-circle-flèche-s' } }); $("#GenderID_FK").selectmenu({ icons: { bouton: 'ui-icon-circle-flèche-s' } }); $("#PackageID_FK").selectmenu({ icons: { bouton: 'ui-icon-circle-flèche-s' } }); });
0
répondu luis 2018-06-05 02:36:39

le but de L'OP est qu'il veut définir les scripts en ligne dans sa vue partielle, que je suppose que ce script est spécifique seulement à cette vue partielle, et que ce bloc soit inclus dans sa section script.

je comprends qu'il veut avoir cette vue partielle pour être autonome. L'idée est similaire aux composants Lorsqu'on utilise Angular.

à Ma façon serait de simplement garder les scripts à l'intérieur de la Vue Partielle. Maintenant le problème avec ça est lors de l'appel de la vue partielle, il peut exécuter le script avant tous les autres scripts (qui est typiquement ajouté au bas de la page de mise en page). Dans ce cas, vous avez juste le script de vue partielle qui attend les autres scripts. Il y a plusieurs façons de le faire. Le plus simple, que j'ai déjà utilisé, est d'utiliser un événement sur body .

sur ma disposition, j'aurais quelque chose en bas comme ceci:

// global scripts
<script src="js/jquery.min.js"></script>
// view scripts
@RenderSection("scripts", false)
// then finally trigger partial view scripts
<script>
  (function(){
    document.querySelector('body').dispatchEvent(new Event('scriptsLoaded'));
  })();
</script>

puis sur mon partiel Vue (en bas):

<script>
  (function(){
    document.querySelector('body').addEventListener('scriptsLoaded', function() {

      // .. do your thing here

    });
  })();
</script>

une autre solution est d'utiliser une pile pour pousser tous vos scripts, et appeler chacun à la fin. Une autre solution, comme déjà mentionné, est Requerjs / AMD pattern, qui fonctionne vraiment bien aussi.

0
répondu alans 2018-08-17 16:36:36

Eh bien, je suppose que les autres affiches vous ont fourni un moyen d'inclure directement une @section dans votre partial (en utilisant des helpers html tiers).

mais, je pense que, si votre script est étroitement couplé à votre partiel, mettez juste votre javascript directement à l'intérieur d'un inline <script> tag dans votre partiel et être fait avec (juste faire attention à la duplication de script si vous avez l'intention d'utiliser le partiel plus d'une fois dans un seul la vue);

-1
répondu Daffy Punk 2016-07-27 14:55:33

supposons que vous avez une vue partielle appelée _contact.cshtml, votre contact peut être un nom (legal) ou un sujet physique (prénom, lastname). votre vue devrait prendre soin de ce qui est rendu et qui peut être atteint avec javascript. ainsi, le rendu différé et la vue intérieure de JS peuvent être nécessaires.

la seule façon que je pense, comment il peut être ommitted, est quand nous créons une manière discrète de traiter de telles préoccupations D'UI.

notez également que MVC 6 Aura Un so appelé view Component, même MVC futures avait quelque chose de similaire et Telerik soutient également une telle chose...

-3
répondu user4298890 2014-11-27 06:57:09

j'ai eu le même problème résolu avec ceci:

@section ***{
@RenderSection("****", required: false)
}

c'est une jolie façon de m'injecter.

-5
répondu Pouria Jafari 2015-08-20 13:01:54