การใช้ส่วนต่างๆในเทมเพลต Editor / Display


104

ฉันต้องการเก็บโค้ด JavaScript ทั้งหมดไว้ในส่วนเดียว ก่อนปิดทำการbodyแท็กในหน้าเค้าโครงหลักของฉันและแค่สงสัยว่าดีที่สุดที่จะพูดถึงสไตล์ MVC

ตัวอย่างเช่นถ้าฉันสร้างไฟล์ DisplayTemplate\DateTime.cshtmlไฟล์ที่ใช้ DateTime Picker ของ jQuery UI มากกว่าที่ฉันจะฝัง JavaScript ลงในเทมเพลตนั้นโดยตรง แต่ไฟล์นั้นจะแสดงผลกลางหน้า

ในมุมมองปกติของฉันฉันสามารถใช้@section JavaScript { //js here }แล้ว@RenderSection("JavaScript", false)ในเค้าโครงหลักของฉัน แต่ดูเหมือนว่าจะใช้ไม่ได้ในเทมเพลตดิสเพลย์ / ตัวแก้ไข - มีความคิดใดบ้าง


4
สำหรับใครก็ตามที่มาในภายหลัง - มีแพ็คเกจ nuget สำหรับจัดการสิ่งนี้: nuget.org/packages/Forloop.HtmlHelpers
Russ Cam

คำตอบ:


189

คุณสามารถดำเนินการร่วมกันของผู้ช่วยสองคน:

public static class HtmlExtensions
{
    public static MvcHtmlString Script(this HtmlHelper htmlHelper, Func<object, HelperResult> template)
    {
        htmlHelper.ViewContext.HttpContext.Items["_script_" + Guid.NewGuid()] = template;
        return MvcHtmlString.Empty;
    }

    public static IHtmlString RenderScripts(this HtmlHelper htmlHelper)
    {
        foreach (object key in htmlHelper.ViewContext.HttpContext.Items.Keys)
        {
            if (key.ToString().StartsWith("_script_"))
            {
                var template = htmlHelper.ViewContext.HttpContext.Items[key] as Func<object, HelperResult>;
                if (template != null)
                {
                    htmlHelper.ViewContext.Writer.Write(template(null));
                }
            }
        }
        return MvcHtmlString.Empty;
    }
}

จากนั้นใน_Layout.cshtml:

<body>
...
@Html.RenderScripts()
</body>

และบางแห่งในบางเทมเพลต:

@Html.Script(
    @<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
)

3
เนื่องจากไม่มีการสั่งพจนานุกรมฉันจะทำก่อนออกก่อนได้อย่างไร คำสั่งที่ออกมาเป็นแบบสุ่ม (น่าจะเป็นเพราะ Guid) ..
eth0

บางทีคุณอาจตั้งค่าฟิลด์จำนวนเต็มคงและใช้ Interlocked.Increment () แทน GUID เพื่อรับคำสั่งซื้อ แต่ถึงอย่างนั้นฉันก็คิดว่าพจนานุกรมไม่รับประกันการสั่งซื้อ ในความคิดที่สองบางทีฟิลด์คงที่อาจจะหลบได้เนื่องจากอาจถูกเก็บไว้ในการแสดงหน้า สามารถเพิ่มจำนวนเต็มลงในพจนานุกรมรายการได้ แต่คุณต้องล็อกไว้
Mark Adamson

ฉันเริ่มใช้โซลูชันนี้เมื่อเร็ว ๆ นี้ แต่ดูเหมือนจะไม่สามารถรวมสองสคริปต์ในบรรทัดเดียว @ Html.Script () ได้เพราะฉันไม่แน่ใจว่า HelperResult ทำงานอย่างไร เป็นไปไม่ได้ที่จะทำ 2 บล็อกสคริปต์ใน 1 Html.Script call?
Langdon

2
@TimMeers คุณหมายถึงอะไร? สำหรับฉันทั้งหมดนี้ล้าสมัยมาโดยตลอด ฉันจะไม่ใช้ตัวช่วยเหล่านั้นเลย ฉันไม่จำเป็นต้องรวมสคริปต์ใด ๆ ในมุมมองบางส่วนของฉัน sectionsฉันก็จะติดกับมาตรฐานมีดโกน ใน MVC4 Bundling สามารถใช้งานได้จริงและช่วยลดขนาดของสคริปต์
Darin Dimitrov

4
วิธีนี้ใช้ไม่ได้หากคุณต้องการวางสคริปต์หรือสไตล์ในheadแท็กแทนที่จะอยู่ที่ท้ายbodyแท็กเนื่องจาก@Html.RenderScripts()จะดำเนินการก่อนมุมมองบางส่วนของคุณและก่อนหน้า@Html.Script()นี้
Vi.

41

คำตอบของดารินฉบับแก้ไขเพื่อความมั่นใจในการสั่งซื้อ ยังใช้งานได้กับ CSS:

public static IHtmlString Resource(this HtmlHelper HtmlHelper, Func<object, HelperResult> Template, string Type)
{
    if (HtmlHelper.ViewContext.HttpContext.Items[Type] != null) ((List<Func<object, HelperResult>>)HtmlHelper.ViewContext.HttpContext.Items[Type]).Add(Template);
    else HtmlHelper.ViewContext.HttpContext.Items[Type] = new List<Func<object, HelperResult>>() { Template };

    return new HtmlString(String.Empty);
}

public static IHtmlString RenderResources(this HtmlHelper HtmlHelper, string Type)
{
    if (HtmlHelper.ViewContext.HttpContext.Items[Type] != null)
    {
        List<Func<object, HelperResult>> Resources = (List<Func<object, HelperResult>>)HtmlHelper.ViewContext.HttpContext.Items[Type];

        foreach (var Resource in Resources)
        {
            if (Resource != null) HtmlHelper.ViewContext.Writer.Write(Resource(null));
        }
    }

    return new HtmlString(String.Empty);
}

คุณสามารถเพิ่มทรัพยากร JS และ CSS ได้ดังนี้:

@Html.Resource(@<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>, "js")
@Html.Resource(@<link rel="stylesheet" href="@Url.Content("~/CSS/style.css")" />, "css")

และแสดงทรัพยากร JS และ CSS ดังนี้:

@Html.RenderResources("js")
@Html.RenderResources("css")

คุณสามารถตรวจสอบสตริงเพื่อดูว่าเริ่มต้นด้วยสคริปต์ / ลิงก์หรือไม่ดังนั้นคุณจึงไม่จำเป็นต้องกำหนดอย่างชัดเจนว่าทรัพยากรแต่ละรายการคืออะไร


ขอบคุณ eth0. ฉันยอมรับปัญหานี้ แต่ฉันจะต้องตรวจสอบ
one.beat.consumer

ฉันรู้เรื่องนี้เมื่อเกือบ 2 ปีที่แล้ว แต่มีวิธีตรวจสอบว่าไฟล์ css / js มีอยู่แล้วและไม่แสดงผลหรือไม่ ขอบคุณ
CodingSlayer

1
ตกลง. ไม่แน่ใจว่ามันมีประสิทธิภาพแค่ไหน แต่ตอนนี้ฉันกำลังทำสิ่งนี้: var httpTemplates = HtmlHelper.ViewContext.HttpContext.Iems [Type] เป็นรายการ <Func <object, HelperResult >>; var prevItem = จาก q ใน httpTemplates โดยที่ q (null) .oString () == เทมเพลท (null) .oString () เลือก q; if (! prevItem.Any ()) {// Add Template}
CodingSlayer

@imAbhi ขอบคุณสิ่งที่ฉันต้องการดูเหมือนการรวมกลุ่ม 1 วงสำหรับรายการ ToString ดังนั้นฉันคิดว่ามันน่าจะเร็วพอ
Kunukn

36

ฉันประสบปัญหาเดียวกัน แต่วิธีแก้ปัญหาที่เสนอที่นี่ใช้ได้ดีสำหรับการเพิ่มการอ้างอิงไปยังทรัพยากรเท่านั้นและไม่เหมาะกับโค้ด JS แบบอินไลน์ ฉันพบบทความที่มีประโยชน์มากและรวม JS แบบอินไลน์ทั้งหมดของฉัน (และแท็กสคริปต์) ไว้ในไฟล์

@using (Html.BeginScripts())
{
    <script src="@Url.Content("~/Scripts/jquery-ui-1.8.18.min.js")" type="text/javascript"></script>
    <script>
    // my inline scripts here
    <\script>
}

และในมุมมอง _Layout ที่วางไว้@Html.PageScripts()ก่อนปิดแท็ก "body" ใช้งานได้เหมือนมีเสน่ห์สำหรับฉัน


ผู้ช่วยเหลือตัวเอง:

public static class HtmlHelpers
{
    private class ScriptBlock : IDisposable
    {
        private const string scriptsKey = "scripts";
        public static List<string> pageScripts
        {
            get
            {
                if (HttpContext.Current.Items[scriptsKey] == null)
                    HttpContext.Current.Items[scriptsKey] = new List<string>();
                return (List<string>)HttpContext.Current.Items[scriptsKey];
            }
        }

        WebViewPage webPageBase;

        public ScriptBlock(WebViewPage webPageBase)
        {
            this.webPageBase = webPageBase;
            this.webPageBase.OutputStack.Push(new StringWriter());
        }

        public void Dispose()
        {
            pageScripts.Add(((StringWriter)this.webPageBase.OutputStack.Pop()).ToString());
        }
    }

    public static IDisposable BeginScripts(this HtmlHelper helper)
    {
        return new ScriptBlock((WebViewPage)helper.ViewDataContainer);
    }

    public static MvcHtmlString PageScripts(this HtmlHelper helper)
    {
        return MvcHtmlString.Create(string.Join(Environment.NewLine, ScriptBlock.pageScripts.Select(s => s.ToString())));
    }
}

3
นี่คือคำตอบที่ดีที่สุด นอกจากนี้ยังช่วยให้คุณฉีดอะไรก็ได้สวย ๆ และเลื่อนออกไปจนกว่าจะสิ้นสุด
drzaus

1
คุณควรคัดลอก - วางโค้ดจากบทความเผื่อว่ามันจะล่ม! นี่คือคำตอบที่ดีเยี่ยม!
Shaamaan

เราจะทำสิ่งนี้ได้อย่างไรใน asp.net core
ramanmittal

13

ฉันชอบวิธีแก้ปัญหาที่โพสต์โดย @ john-w-harding ดังนั้นฉันจึงรวมเข้ากับคำตอบโดย @ darin-dimitrov เพื่อทำให้โซลูชันที่ซับซ้อนต่อไปนี้อาจทำให้คุณล่าช้าในการแสดงผล html (สคริปต์ด้วย) ภายในบล็อกที่ใช้

การใช้งาน

ในการดูบางส่วนซ้ำให้รวมบล็อกเพียงครั้งเดียว:

@using (Html.Delayed(isOnlyOne: "MYPARTIAL_scripts")) {
    <script>
        someInlineScript();
    </script>
}

ในมุมมองบางส่วน (ซ้ำ?) ให้รวมบล็อกทุกครั้งที่ใช้บางส่วน:

@using (Html.Delayed()) {
    <b>show me multiple times, @Model.Whatever</b>
}

ในมุมมองบางส่วน (ซ้ำ?) ให้รวมบล็อกหนึ่งครั้งและแสดงผลโดยเฉพาะตามชื่อในภายหลังone-time:

@using (Html.Delayed("one-time", isOnlyOne: "one-time")) {
    <b>show me once by name</b>
    <span>@Model.First().Value</span>
}

ในการแสดงผล:

@Html.RenderDelayed(); // the "default" unidentified blocks
@Html.RenderDelayed("one-time", false); // render the specified block by name, and allow us to render it again in a second call
@Html.RenderDelayed("one-time"); // render the specified block by name
@Html.RenderDelayed("one-time"); // since it was "popped" in the last call, won't render anything

รหัส

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


}

แปลก. ฉันจำไม่ได้ว่าคัดลอกคำตอบของหัวข้ออื่นนี้แต่ฉันเขียนได้ดีกว่าเล็กน้อยที่นั่น ...
drzaus

12

ติดตั้งForloop.HtmlHelpersแพคเกจ nuget - จะเพิ่มผู้ช่วยบางส่วนสำหรับการจัดการสคริปต์ในมุมมองบางส่วนและแม่บรรณาธิการ

คุณต้องโทรหาที่ไหนสักแห่งในเค้าโครงของคุณ

@Html.RenderScripts()

นี่คือที่ที่ไฟล์สคริปต์และบล็อกสคริปต์จะถูกส่งออกในหน้าดังนั้นฉันขอแนะนำให้วางไว้หลังสคริปต์หลักของคุณในเค้าโครงและหลังส่วนสคริปต์ (ถ้าคุณมี)

หากคุณกำลังใช้ Web Optimization Framework ร่วมกับบันเดิลคุณสามารถใช้โอเวอร์โหลดได้

@Html.RenderScripts(Scripts.Render)

เพื่อให้วิธีนี้ใช้สำหรับการเขียนไฟล์สคริปต์

ตอนนี้ทุกเวลาที่คุณต้องการเพิ่มไฟล์สคริปต์หรือบล็อกในมุมมองมุมมองบางส่วนหรือเทมเพลตเพียงแค่ใช้

@using (Html.BeginScriptContext())
{
  Html.AddScriptFile("~/Scripts/jquery.validate.js");
  Html.AddScriptBlock(
    @<script type="text/javascript">
       $(function() { $('#someField').datepicker(); });
     </script>
  );
}

ผู้ช่วยเหลือตรวจสอบให้แน่ใจว่ามีการแสดงการอ้างอิงไฟล์สคริปต์เพียงรายการเดียวหากมีการเพิ่มหลายครั้งและยังช่วยให้มั่นใจได้ว่าไฟล์สคริปต์จะแสดงผลตามลำดับที่คาดไว้เช่น

  1. เค้าโครง
  2. บางส่วนและเทมเพลต (ตามลำดับที่ปรากฏในมุมมองจากบนลงล่าง)

5

โพสต์นี้ช่วยฉันได้มากดังนั้นฉันจึงคิดว่าฉันจะโพสต์การนำแนวคิดพื้นฐานไปใช้ ฉันได้แนะนำฟังก์ชันตัวช่วยที่สามารถส่งคืนแท็กสคริปต์เพื่อใช้ในฟังก์ชัน @ Html.Resource

ฉันยังเพิ่มคลาสแบบคงที่อย่างง่ายเพื่อให้ฉันสามารถใช้ตัวแปรที่พิมพ์เพื่อระบุทรัพยากร JS หรือ CSS

public static class ResourceType
{
    public const string Css = "css";
    public const string Js = "js";
}

public static class HtmlExtensions
{
    public static IHtmlString Resource(this HtmlHelper htmlHelper, Func<object, dynamic> template, string Type)
    {
        if (htmlHelper.ViewContext.HttpContext.Items[Type] != null) ((List<Func<object, dynamic>>)htmlHelper.ViewContext.HttpContext.Items[Type]).Add(template);
        else htmlHelper.ViewContext.HttpContext.Items[Type] = new List<Func<object, dynamic>>() { template };

        return new HtmlString(String.Empty);
    }

    public static IHtmlString RenderResources(this HtmlHelper htmlHelper, string Type)
    {
        if (htmlHelper.ViewContext.HttpContext.Items[Type] != null)
        {
            List<Func<object, dynamic>> resources = (List<Func<object, dynamic>>)htmlHelper.ViewContext.HttpContext.Items[Type];

            foreach (var resource in resources)
            {
                if (resource != null) htmlHelper.ViewContext.Writer.Write(resource(null));
            }
        }

        return new HtmlString(String.Empty);
    }

    public static Func<object, dynamic> ScriptTag(this HtmlHelper htmlHelper, string url)
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
        var script = new TagBuilder("script");
        script.Attributes["type"] = "text/javascript";
        script.Attributes["src"] = urlHelper.Content("~/" + url);
        return x => new HtmlString(script.ToString(TagRenderMode.Normal));
    }
}

และในการใช้งาน

@Html.Resource(Html.ScriptTag("Areas/Admin/js/plugins/wysiwyg/jquery.wysiwyg.js"), ResourceType.Js)

ขอขอบคุณที่ @Darin ดิมิทรอฟที่จัดมาให้คำตอบในคำถามของฉันที่นี่


2

คำตอบที่ให้ในการเติมส่วนมีดโกนจากบางส่วนโดยใช้RequireScriptHtmlHelper เป็นไปตามรูปแบบเดียวกัน นอกจากนี้ยังมีประโยชน์ที่จะตรวจสอบและยับยั้งการอ้างอิงซ้ำกับ URL Javascript เดียวกันและมีpriorityพารามิเตอร์ที่ชัดเจนที่สามารถใช้เพื่อควบคุมการสั่งซื้อ

ฉันขยายโซลูชันนี้โดยเพิ่มวิธีการสำหรับ:

// use this for scripts to be placed just before the </body> tag
public static string RequireFooterScript(this HtmlHelper html, string path, int priority = 1) { ... }
public static HtmlString EmitRequiredFooterScripts(this HtmlHelper html) { ... }

// use this for CSS links
public static string RequireCSS(this HtmlHelper html, string path, int priority = 1) { ... }
public static HtmlString EmitRequiredCSS(this HtmlHelper html) { ... }

ฉันชอบโซลูชันของ Darin & eth0 เนื่องจากพวกเขาใช้HelperResultเทมเพลตซึ่งอนุญาตให้ใช้สคริปต์และบล็อก CSS ไม่ใช่แค่ลิงก์ไปยังไฟล์ Javascript และ CSS


1

คำตอบของ @Darin Dimitrov และ @ eth0 เพื่อใช้กับการใช้งาน Bundle Extention:

@Html.Resources(a => new HelperResult(b => b.Write( System.Web.Optimization.Scripts.Render("~/Content/js/formBundle").ToString())), "jsTop")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.