javascript - आंशिक से एक रेजर अनुभाग पॉप्युलेट करें




asp.net-mvc-3 razor (8)

ऐसा करने का प्रयास करने के लिए मेरा मुख्य प्रेरणा जावास्क्रिप्ट प्राप्त करना है जो केवल पृष्ठ के निचले हिस्से में आंशिक रूप से जावास्क्रिप्ट के साथ आवश्यक है, न कि पृष्ठ के मध्य में जहां आंशिक प्रदान किया जाता है।

मैं जो करने की कोशिश कर रहा हूं उसका सरलीकृत उदाहरण यहां दिया गया है:

शरीर से ठीक पहले एक स्क्रिप्ट अनुभाग के साथ लेआउट है।

<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />    
</head>

<body>
    @RenderBody()
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
    @RenderSection("Scripts", false)
</body>
</html>

इस लेआउट का उपयोग कर एक उदाहरण देखें।

<h2>This is the view</h2>

@{Html.RenderPartial("_Partial");}

@section Scripts {
<script type="text/javascript">
        alert("I'm a view.");
</script>
}

और यहां आंशिक रूप से दृश्य से प्रस्तुत किया जा रहा है।

<p>This is the partial.</p>

@* this never makes it into the rendered page *@
@section Scripts {
<script type="text/javascript">
    alert("I'm a partial."); 
</script>
}

इस उदाहरण में, दृश्य में निर्दिष्ट मार्कअप अनुभाग में रखा गया है, लेकिन आंशिक से मार्कअप नहीं है। क्या रेज़र के साथ आंशिक दृश्य से एक अनुभाग को पॉप्युलेट करना संभव है? यदि नहीं, तो जावास्क्रिप्ट प्राप्त करने के कुछ अन्य तरीके क्या हैं जिन्हें पृष्ठ के निचले भाग में केवल वैश्विक स्तर पर शामिल किए बिना आंशिक रूप से आवश्यक है?


आंशिक विचार उनके माता-पिता के विचारों में भाग नहीं ले सकते हैं।


आप एक नया Layout पेज बना सकते हैं और पार्टिअल व्यू को एक पूर्ण दृश्य के अंदर लपेट सकते हैं जो सामग्री को प्रस्तुत करने और किसी भी लाइब्रेरी अनुभागों के लिए ज़िम्मेदार है।

उदाहरण के लिए, मान लें कि मेरे पास निम्न कोड है:

HomeController.cs

[HttpGet]
public ActionResult About()
{
    var vm = new AboutViewModel();
    return View("About", vm);
}

जब पूर्ण पृष्ठ दृश्य प्रस्तुत किया जाता है, तो यह आम तौर पर दो फाइलों को विलय कर देता है:

About.cshtml

@model AboutViewModel

@{
    ViewBag.Title = "About CSHN";
}

<h3>@ViewBag.Title</h3>

@section Styles {
    <style> /* style info here */ </style>
}

@section Scripts {
    <script> /* script info here */ </script>
}

_Layout.cshtml (या जो भी _ViewStart में निर्दिष्ट है या पृष्ठ में ओवरराइड किया गया है)

<!DOCTYPE html>

<html>
<head>
    @RenderSection("Styles", false)
    <title>@ViewBag.Title</title>
</head>
<body>
    @RenderBody()

    @RenderSection("scripts", false)
</body>
</html>

अब , मान लें कि आप आंशिक दृश्य के रूप में About.cshtml को प्रस्तुत करना चाहते हैं, शायद AJAX कॉल के जवाब में मोडल विंडो के रूप में। लक्ष्य यहां केवल पृष्ठ, स्क्रिप्ट और सभी में उल्लिखित सामग्री को वापस करने के लिए है, बिना सभी _Layout.cshtml मास्टर लेआउट (जैसे एक पूर्ण <html> दस्तावेज़) में शामिल है।

आप इसे इस तरह से आजमा सकते हैं, लेकिन यह किसी भी अनुभाग ब्लॉक के साथ नहीं आएगा:

return PartialView("About", vm);

इसके बजाए, इस तरह एक सरल लेआउट पेज जोड़ें:

_PartialLayout.cshtml

<div>
    @RenderBody()
    @RenderSection("Styles", false)
    @RenderSection("scripts", false)
</div>

या इस तरह एक मोडल विंडो का समर्थन करने के लिए:

_ModalLayout.cshtml

<div class="modal modal-page fade" tabindex="-1" role="dialog" >
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">

            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title">@ViewBag.Title</h4>
            </div>

            <div class="modal-body">

                @RenderBody()
                @RenderSection("Styles", false)
                @RenderSection("scripts", false)

            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-inverse" data-dismiss="modal">Dismiss</button>
            </div>
        </div>
    </div>
</div>

फिर आप इस नियंत्रक या किसी अन्य हैंडलर में एक कस्टम मास्टर व्यू निर्दिष्ट कर सकते हैं जिसे आप एक साथ दृश्य की सामग्री और स्क्रिप्ट प्रस्तुत करना चाहते हैं

[HttpGet]
public ActionResult About()
{
    var vm = new AboutViewModel();
    return !Request.IsAjaxRequest()
              ? View("About", vm)
              : View("About", "~/Views/Shared/_ModalLayout.cshtml", vm);
}

ऊपर श्री बेल और शिमी के जवाब पर आधार, मैं बंडल लिपि के लिए अतिरिक्त समारोह में जोड़ता हूं।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Web.Mvc;
namespace ABC.Utility
{
public static  class PartialViewHelper
{
    public static string RequireScript(this HtmlHelper html, string path, int priority = 1)
    {
        var requiredScripts = HttpContext.Current.Items["RequiredScripts"] as List<ResourceInclude>;
        if (requiredScripts == null) HttpContext.Current.Items["RequiredScripts"] = requiredScripts = new List<ResourceInclude>();
        if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path, Priority = priority });
        return null;
    }

    public static string RequireBundleStyles(this HtmlHelper html, string bundleName)
    {
        var a = System.Web.Optimization.Styles.Render(bundleName);
        var requiredStyles = HttpContext.Current.Items["RequiredStyles"] as IHtmlString;
        if (requiredStyles == null) HttpContext.Current.Items["RequiredStyles"] = requiredStyles = a;
        return null;
    }

    public static string RequireBundleScripts(this HtmlHelper html, string bundleName)
    {
        var a=System.Web.Optimization.Scripts.Render(bundleName);
        var requiredScripts = HttpContext.Current.Items["RequiredScripts"] as IHtmlString;
        if (requiredScripts == null) HttpContext.Current.Items["RequiredScripts"] = requiredScripts = a;
        return null;
    }

    public static HtmlString EmitRequiredBundleStyles(this HtmlHelper html)
    {
        var requiredStyles = HttpContext.Current.Items["RequiredStyles"] as IHtmlString;
        if (requiredStyles == null) return null;
        return MvcHtmlString.Create(requiredStyles.ToHtmlString()) ;
    }

    public static HtmlString EmitRequiredBundleScripts(this HtmlHelper html)
    {
        var requiredScripts = HttpContext.Current.Items["RequiredScripts"] as IHtmlString;
        if (requiredScripts == null) return null;
        return MvcHtmlString.Create(requiredScripts.ToHtmlString());
    }

    public static HtmlString EmitRequiredScripts(this HtmlHelper html)
    {
        var requiredScripts = HttpContext.Current.Items["RequiredScripts"] as List<ResourceInclude>;
        if (requiredScripts == null) return null;
        StringBuilder sb = new StringBuilder();
        foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
        {
            sb.AppendFormat("<script src=\"{0}\" type=\"text/javascript\"></script>\n", item.Path);
        }
        return new HtmlString(sb.ToString());
    }
    public class ResourceInclude
    {
        public string Path { get; set; }
        public int Priority { get; set; }
    }
}//end class
}// end namespace  

पार्टियल व्यू पर नमूना: - @ एचटीएमएल। रिक्वेयरबंडल स्टाइल ("~ / बंडल / फ़ाइल अपलोड / बूटस्ट्रैप / बेसिकप्लसयूआई / सीएसएस"); @ Html.RequireBundleScripts ( "~ / बंडलों / fileupload / बूटस्ट्रैप / BasicPlusUI / js");

मास्टरपेज पर नमूना: - @ एचटीएमएल.इमिटआरक्वर्डबंडल स्टाइल ()


ऐसा करने का अधिक सुरुचिपूर्ण तरीका आंशिक दृश्य स्क्रिप्ट को अलग फ़ाइल में ले जाना है और फिर दृश्य के स्क्रिप्ट अनुभाग में इसे प्रस्तुत करना है:

<h2>This is the view</h2>

@Html.RenderPartial("_Partial")

@section Scripts
{
    @Html.RenderPartial("_PartialScripts")

    <script type="text/javascript">
        alert("I'm a view script.");
    </script>
}

आंशिक दृश्य _ Partial.cshtml :

<p>This is the partial.</p>

आंशिक दृश्य _ PartialScripts.cshtml केवल स्क्रिप्ट के साथ:

<script type="text/javascript">
    alert("I'm a partial script!");
</script>

पेज में बाद में किसी भी सामग्री (स्क्रिप्ट या सिर्फ HTML) प्रस्तुत करने के लिए https://.com/a/18790222/1037948 उत्तर से @using(Html.Delayed()){ ...your content... } एक्सटेंशन का उपयोग https://.com/a/18790222/1037948 । आंतरिक Queue सही क्रम सुनिश्चित करना चाहिए।


यह कार्यक्षमता ClientDependency.Core.Mvc.dll में भी लागू की गई है। यह एचटीएमएल हेल्पर्स प्रदान करता है: @ एचटीएमएल.रूक्वाययरजेएस और @ एचटीएमएल। रेंडरजेसहेर ()। Nuget पैकेज: क्लाइंट निर्भरता-एमवीसी


Forloop.HtmlHelpers nuget पैकेज स्थापित करें - यह आंशिक दृश्यों और संपादक टेम्पलेट्स में स्क्रिप्ट प्रबंधित करने के लिए कुछ सहायक जोड़ता है।

कहीं भी आपके लेआउट में, आपको कॉल करने की आवश्यकता है

@Html.RenderScripts()

यह वह जगह होगी जहां पृष्ठ में कोई स्क्रिप्ट फ़ाइलें और स्क्रिप्ट ब्लॉक आउटपुट किए जाएंगे, इसलिए मैं इसे लेआउट में अपनी मुख्य स्क्रिप्ट के बाद और स्क्रिप्ट अनुभाग (यदि आपके पास है) के बाद इसे डालने की अनुशंसा करता हूं।

यदि आप बंडलिंग के साथ वेब ऑप्टिमाइज़ेशन फ्रेमवर्क का उपयोग कर रहे हैं, तो आप अधिभार का उपयोग कर सकते हैं

@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. आंशिक और टेम्पलेट्स (जिस क्रम में वे दृश्य में दिखाई देते हैं, ऊपर से नीचे)

[अद्यतन संस्करण] इनलाइन स्क्रिप्ट शामिल करने के लिए @Necrocubus प्रश्न के बाद अद्यतन संस्करण।

public static class ScriptsExtensions
{
    const string REQ_SCRIPT = "RequiredScript";
    const string REQ_INLINESCRIPT = "RequiredInlineScript";
    const string REQ_STYLE = "RequiredStyle";

    #region Scripts
    /// <summary>
    /// Adds a script 
    /// </summary>
    /// <param name="html"></param>
    /// <param name="path"></param>
    /// <param name="priority">Ordered by decreasing priority </param>
    /// <param name="bottom"></param>
    /// <param name="options"></param>
    /// <returns></returns>
    public static string RequireScript(this IHtmlHelper html, string path, int priority = 1, bool bottom=false, params string[] options)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceToInclude>;
        if (requiredScripts == null) ctxt.Items[REQ_SCRIPT] = requiredScripts = new List<ResourceToInclude>();
        if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceToInclude() { Path = path, Priority = priority, Options = options, Type=ResourceType.Script, Bottom=bottom});
        return null;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="html"></param>
    /// <param name="script"></param>
    /// <param name="priority">Ordered by decreasing priority </param>
    /// <param name="bottom"></param>
    /// <returns></returns>
    public static string RequireInlineScript(this IHtmlHelper html, string script, int priority = 1, bool bottom = false)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_INLINESCRIPT] as List<InlineResource>;
        if (requiredScripts == null) ctxt.Items[REQ_INLINESCRIPT] = requiredScripts = new List<InlineResource>();
        requiredScripts.Add(new InlineResource() { Content=script, Priority = priority, Bottom=bottom, Type=ResourceType.Script});
        return null;
    }

    /// <summary>
    /// Just call @Html.EmitRequiredScripts(false)
    /// at the end of your head tag and 
    /// @Html.EmitRequiredScripts(true) at the end of the body if some scripts are set to be at the bottom.
    /// </summary>
    public static HtmlString EmitRequiredScripts(this IHtmlHelper html, bool bottom)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceToInclude>;
        var requiredInlineScripts = ctxt.Items[REQ_INLINESCRIPT] as List<InlineResource>;
        var scripts = new List<Resource>();
        scripts.AddRange(requiredScripts ?? new List<ResourceToInclude>());
        scripts.AddRange(requiredInlineScripts ?? new List<InlineResource>());
        if (scripts.Count==0) return null;
        StringBuilder sb = new StringBuilder();
        foreach (var item in scripts.Where(s=>s.Bottom==bottom).OrderByDescending(i => i.Priority))
        {
            sb.Append(item.ToString());
        }
        return new HtmlString(sb.ToString());
    }
    #endregion Scripts

    #region Styles
    /// <summary>
    /// 
    /// </summary>
    /// <param name="html"></param>
    /// <param name="path"></param>
    /// <param name="priority">Ordered by decreasing priority </param>
    /// <param name="options"></param>
    /// <returns></returns>
    public static string RequireStyle(this IHtmlHelper html, string path, int priority = 1, params string[] options)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceToInclude>;
        if (requiredScripts == null) ctxt.Items[REQ_STYLE] = requiredScripts = new List<ResourceToInclude>();
        if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceToInclude() { Path = path, Priority = priority, Options = options });
        return null;
    }

    /// <summary>
    /// Just call @Html.EmitRequiredStyles()
    /// at the end of your head tag
    /// </summary>
    public static HtmlString EmitRequiredStyles(this IHtmlHelper html)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceToInclude>;
        if (requiredScripts == null) return null;
        StringBuilder sb = new StringBuilder();
        foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
        {
            sb.Append(item.ToString());
        }
        return new HtmlString(sb.ToString());
    }
    #endregion Styles

    #region Models
    public class InlineResource : Resource
    {
        public string Content { get; set; }
        public override string ToString()
        {
            return "<script>"+Content+"</script>";
        }
    }

    public class ResourceToInclude : Resource
    {
        public string Path { get; set; }
        public string[] Options { get; set; }
        public override string ToString()
        {
            switch(Type)
            {
                case ResourceType.CSS:
                    if (Options == null || Options.Length == 0)
                        return String.Format("<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\" />\n", Path);
                    else
                        return String.Format("<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\" {1} />\n", Path, String.Join(" ", Options));
                default:
                case ResourceType.Script:
                    if (Options == null || Options.Length == 0)
                        return String.Format("<script src=\"{0}\" type=\"text/javascript\"></script>\n", Path);
                    else
                        return String.Format("<script src=\"{0}\" type=\"text/javascript\" {1}></script>\n", Path, String.Join(" ", Options));
            }
        }
    }
    public class Resource
    {
        public ResourceType Type { get; set; }
        public int Priority { get; set; }
        public bool Bottom { get; set; }
    }
    public enum ResourceType
    {
        Script,
        CSS
    }
    #endregion Models
}

मेरे 2 सेंट, यह एक पुरानी पोस्ट है, लेकिन अभी भी प्रासंगिक है, इसलिए यहां श्री बेल के समाधान का एक अपग्रेड किया गया अपडेट है जो एएसपी.Net कोर के साथ काम करता है।

यह आयातित आंशिक विचारों और सबव्यूव्स से मुख्य लेआउट में स्क्रिप्ट और शैलियों को जोड़ने की अनुमति देता है, और स्क्रिप्ट / स्टाइल आयात (जैसे एसिंक डीफर इत्यादि) में विकल्प जोड़ने की संभावना:

public static class ScriptsExtensions
{
    const string REQ_SCRIPT = "RequiredScript";
    const string REQ_STYLE = "RequiredStyle";

    public static string RequireScript(this IHtmlHelper html, string path, int priority = 1, params string[] options)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceInclude>;
        if (requiredScripts == null) ctxt.Items[REQ_SCRIPT] = requiredScripts = new List<ResourceInclude>();
        if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path, Priority = priority, Options = options });
        return null;
    }


    public static HtmlString EmitRequiredScripts(this IHtmlHelper html)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceInclude>;
        if (requiredScripts == null) return null;
        StringBuilder sb = new StringBuilder();
        foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
        {
            if (item.Options == null || item.Options.Length == 0)
                sb.AppendFormat("<script src=\"{0}\" type=\"text/javascript\"></script>\n", item.Path);
            else
                sb.AppendFormat("<script src=\"{0}\" type=\"text/javascript\" {1}></script>\n", item.Path, String.Join(" ", item.Options));

        }
        return new HtmlString(sb.ToString());
    }


    public static string RequireStyle(this IHtmlHelper html, string path, int priority = 1, params string[] options)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceInclude>;
        if (requiredScripts == null) ctxt.Items[REQ_STYLE] = requiredScripts = new List<ResourceInclude>();
        if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path, Priority = priority, Options = options });
        return null;
    }


    public static HtmlString EmitRequiredStyles(this IHtmlHelper html)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceInclude>;
        if (requiredScripts == null) return null;
        StringBuilder sb = new StringBuilder();
        foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
        {
            if (item.Options == null || item.Options.Length == 0)
                sb.AppendFormat("<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\" />\n", item.Path);
            else
                sb.AppendFormat("<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\" {1} />\n", item.Path, String.Join(" ", item.Options));
        }
        return new HtmlString(sb.ToString());
    }


    public class ResourceInclude
    {
        public string Path { get; set; }
        public int Priority { get; set; }
        public string[] Options { get; set; }
    }
}






razor