asp.net core - टैग तत्व के आगे के बजाय पृष्ठ के निचले हिस्से, टैगहेल्पर प्रक्रिया पद्धति में उत्पन्न स्क्रिप्ट को कैसे प्रस्तुत करें?




asp.net-core tag-helpers (4)

मैं TagHelper वर्ग की प्रक्रिया पद्धति में स्क्रिप्ट उत्पन्न कर रहा हूं

[TargetElement("MyTag")]
    public Class MYClass: TagHelper{
      public override void Process(TagHelperContext context, TagHelperOutput output)
        {
StringBuilder builder = new StringBuilder();

                builder.Append("<script>");
                builder.Append("//some javascript codes here);
                builder.Append("</script>");
                output.Content.Append(builder.ToString());
}
}

अब यह टैग तत्व के बगल में स्क्रिप्ट को अपने भाई के रूप में रखता है।

मुझे शरीर अनुभाग के अंत में लिपियों को स्थान देना होगा।


एक @section scripts {} जो @RenderSection("scripts") साथ लेआउट पर प्रदान की गई है और एक स्क्रिप्ट अनुभाग में अपने टैग सहायक को रखें। प्रदान किए जाने पर, यह उस स्थान पर रखा जाएगा जहां लेआउट पर परिभाषित किया गया है (अपने HTML के नीचे)।

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div>
        <p>some html ... bla bla bla</p>
        @RenderBody()
    </div>
    @RenderSection("scripts", required: false)
</body>
</html>

फिर किसी भी अन्य cshtml फ़ाइल पर,

<p>Some page</p>
@section scripts {
    <mytaghelper>foo</mytaghelper>
}

मुझे विश्वास नहीं है कि टैगहेल्पर के अंदर से नीचे की तरफ या कहीं और स्क्रिप्ट जोड़ने के लिए संभव है, लेकिन टैग का स्थान जो टैगहेल्टर प्रदान कर रहा है। मुझे लगता है कि अगर टैगहेल्वर कुछ बाहरी जेएस फाइल पर निर्भर करता है तो यह टैगहेल्वर की जिम्मेदारी स्वयं को स्क्रिप्ट जोड़ने के लिए नहीं होना चाहिए। उदाहरण के लिए, मान्यता टैगवेलर्स में बनाया गया है:

<span asp-validation-for="Email" class="text-danger"></span>

सभी सत्यापन टैगहेल्गर डेटा-एट्रिब्यूट्स के साथ स्पैन को सजाने के लिए है, यह पेज पर कोई स्क्रिप्ट नहीं जोड़ता है और डेटा-एट्रिब्यूट्स को अनदेखा कर दिया जाएगा यदि स्क्रिप्ट अनुपलब्ध हैं

मान लें कि एक दृश्य में एकाधिक सत्यापन टैगहेल्वर का उपयोग किया जा सकता है और हम नहीं चाहते कि हर एक को एक और स्क्रिप्ट जोड़ना चाहिए।

वी.एस. स्टार्टर वेब एप टेम्प्लेट में आप देख सकते हैं कि सत्यापन स्क्रिप्ट दृश्य के निचले भाग में आंशिक दृश्य (उदाहरण के लिए Login.cshtml) के द्वारा जोड़े जाते हैं

@{await Html.RenderPartialAsync("_ValidationScriptsPartial"); }

स्क्रिप्ट शामिल करने के लिए एक संभव रणनीति है आपका टैगहेल्पर IHttpContextAccessor अपने निर्माता में ले सकता है, इसलिए इसे DI द्वारा इंजेक्ट किया जाएगा, फिर आप HttpContext.Items संग्रह तक पहुंच सकते हैं और एक स्क्रिप्ट की आवश्यकता को इंगित करने के लिए एक चर जोड़ सकते हैं, फिर आंशिक दृश्य में जो स्क्रिप्ट जोड़ता है, आप जो स्क्रिप्ट को शामिल करने के लिए तय किए गए वेरिएबल का पता लगा सकते हैं।

लेकिन मुझे लगता है कि यह सिर्फ स्क्रिप्ट को जोड़ने के लिए और अधिक सरल है जहां फैंसी पाने की कोशिश करने और चीजों को स्वचालित रूप से जोड़ने की बजाय टैगहेल्गर के उपयोग को समर्थन देने के लिए आवश्यक है।

यह विचार केवल जेएस फ़ाइलों के लिए काम करेगा जो कि जेएस के लिए गतिशील रूप से टैगहेल्पर के अंदर लिखा हुआ नहीं है, लेकिन ऐसी लिपियों के लिए बेहतर नहीं है और यदि संभव हो तो बाहरी स्क्रिप्ट फ़ाइलों का उपयोग करें। यदि आपको टैगहेल्गर के अंदर स्क्रिप्ट उत्पन्न करने की आवश्यकता है तो मुझे लगता है कि आप केवल उस तत्व के स्थान पर प्रस्तुत कर पाएंगे जो टैगहेल्टर प्रोसेसिंग हो।


मैंने कस्टम टैग सहायकों की एक जोड़ी बनाई है जो आपकी समस्या को हल करने में सक्षम हैं।

सबसे पहले एक <storecontent> और यह केवल <storecontent> लिपटे गए HTML सामग्री को संग्रहीत करता है। यह सीधे आउटपुट प्रदान नहीं करता है सामग्री एक इनलाइन स्क्रिप्ट या किसी अन्य HTML हो सकती है इस तरह के कई टैग सेवकों को विभिन्न स्थानों में रखा जा सकता है जैसे आंशिक दृश्यों में।

दूसरा टैग सहायक है <renderstoredcontent> और यह इच्छित सामग्री पर सभी पहले से संग्रहीत सामग्री उदाहरण देता है जैसे शरीर के तत्व के अंत में।

StoreContentTagHelper.cs लिए कोड:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;


namespace YourProjectHere.TagHelpers
{
    [TargetElement("storecontent", Attributes = KeyAttributeName)]
    public class StoreContentTagHelper : TagHelper
    {
        private const string KeyAttributeName = "asp-key";
        private const string _storageKey = "storecontent";
        private const string _defaultListKey = "DefaultKey";

        [HtmlAttributeNotBound]
        [ViewContext]
        public ViewContext ViewContext { get; set; }

        [HtmlAttributeName(KeyAttributeName)]
        public string Key { get; set; }

        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            output.SuppressOutput();
            TagHelperContent childContent = await context.GetChildContentAsync();

            var storageProvider = ViewContext.TempData;
            Dictionary<string, List<HtmlString>> storage;
            List<HtmlString> defaultList;

            if (!storageProvider.ContainsKey(_storageKey) || !(storageProvider[_storageKey] is Dictionary<string,List<HtmlString>>))
            {
                storage = new Dictionary<string, List<HtmlString>>();
                storageProvider[_storageKey] = storage;
                defaultList = new List<HtmlString>();
                storage.Add(_defaultListKey, defaultList);
            }
            else
            {
                storage = ViewContext.TempData[_storageKey] as Dictionary<string, List<HtmlString>>;
                if (storage.ContainsKey(_defaultListKey))
                {
                    defaultList = storage[_defaultListKey];

                }
                else
                {
                    defaultList = new List<HtmlString>();
                    storage.Add(_defaultListKey, defaultList);
                }
            }

            if (String.IsNullOrEmpty(Key))
            {
                defaultList.Add(new HtmlString(childContent.GetContent()));
            }
            else
            {
                if(storage.ContainsKey(Key))
                {
                    storage[Key].Add(new HtmlString(childContent.GetContent()));
                }
                else
                {
                    storage.Add(Key, new List<HtmlString>() { new HtmlString(childContent.GetContent()) });
                }
            }
        }
    } 
} 

RenderStoredContentTagHelper.cs लिए कोड:

using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;


namespace YourProjectHere.TagHelpers
{
    [TargetElement("renderstoredcontent", Attributes = KeyAttributeName)]
    public class RenderStoredContentTagHelper : TagHelper
    {
        private const string KeyAttributeName = "asp-key";
        private const string _storageKey = "storecontent";

        [HtmlAttributeNotBound]
        [ViewContext]
        public ViewContext ViewContext { get; set; }

        [HtmlAttributeName(KeyAttributeName)]
        public string Key { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = String.Empty;

            var storageProvider = ViewContext.TempData;
            Dictionary<string, List<HtmlString>> storage;

            if (!storageProvider.ContainsKey(_storageKey) || !(storageProvider[_storageKey] is Dictionary<string, List<HtmlString>>))
            {
                return;
            }

            storage = storageProvider[_storageKey] as Dictionary<string, List<HtmlString>>;
            string html = "";

            if (String.IsNullOrEmpty(Key))
            {
                html = String.Join("", storage.Values.SelectMany(x => x).ToList());
            }
            else
            {
                if (!storage.ContainsKey(Key)) return;
                html = String.Join("", storage[Key]);
            }

            TagBuilder tagBuilder = new TagBuilder("dummy");
            tagBuilder.InnerHtml = html;
            output.Content.SetContent(tagBuilder.InnerHtml);
        }
    } 
} 

बेसिक उपयोग:

कुछ दृश्य या आंशिक दृश्य में:

<storecontent asp-key="">
  <script>
    your inline script...
  </script>
</storecontent>

दूसरे स्थान पर:

<storecontent asp-key="">
  <script src="..."></script>
</storecontent>

और अंत में वांछित स्थान पर जहां दोनों लिपियों को गाया जाना चाहिए:

<renderstoredcontent asp-key=""></renderstoredcontent>

बस।

कुछ नोट्स:

  1. इसमें कोई भी <storecontent> टैग हो सकता है कम से कम रिक्त "" asp-key विशेषता की आवश्यकता है। यदि आप इस विशेषता के लिए विशिष्ट मान निर्दिष्ट करते हैं, तो आप संग्रहीत सामग्री को समूहित कर सकते हैं और विशिष्ट समूहों को विभिन्न स्थानों पर प्रस्तुत कर सकते हैं। यदि आप asp-key="scripts" साथ कुछ सामग्री निर्दिष्ट करते हैं और asp-key="footnotes" साथ कुछ अन्य सामग्री निर्दिष्ट करते हैं तो आप निम्न स्थान का उपयोग करके केवल कुछ समूह को ही प्रस्तुत कर सकते हैं:

<renderstoredcontent asp-key="scripts"></renderstoredcontent>

दूसरे समूह "फ़ुटनोट्स" को दूसरे स्थान पर प्रदान किया जा सकता है

  1. <storecontent> को <renderstoredcontent> लागू करने से पहले परिभाषित किया जाना चाहिए। एएसपी.नेट में प्रतिक्रिया रिवर्स पदानुक्रमित क्रम में उत्पन्न होती है, सबसे पहले सबसे आंतरिक आंशिक दृश्य उत्पन्न होते हैं, फिर माता-पिता आंशिक दृश्य, मुख्य दृश्य और आखिरकार लेआउट पृष्ठ। इसलिए आप आसानी से इन टैग सहायकों को आंशिक दृश्य में स्क्रिप्ट परिभाषित करने के लिए उपयोग कर सकते हैं और फिर लेआउट पृष्ठ में शरीर अनुभाग के अंत में स्क्रिप्ट प्रस्तुत कर सकते हैं।

  2. कमांड @addTagHelper "*, YourProjectHere" का उपयोग करके _ViewImports.cshtml फ़ाइल में अपने कस्टम टैग हैयररों को संदर्भित करने के लिए मत भूलें।

लंबी पोस्ट के लिए क्षमा करें, और मुझे आशा है कि यह मदद करता है!


पृष्ठ के निचले हिस्से में जावास्क्रिप्ट डालने के बजाय आप एक कदम आगे जा सकते हैं और पूरी तरह से अपने जावास्क्रिप्ट से अपने html (टैगहेल्पर) को अलग कर सकते हैं। अपना जावास्क्रिप्ट लिखें ताकि यह आपके टैगहेल्पर को ढूंढ सके और खुद को आरंभ कर सके।

यहां एक उदाहरण के तौर पर एक टैगवेल्पर / जावास्क्रिप्ट है जो कि यूटीसी डेटटाइम लेता है और इसे उपयोगकर्ताओं के स्थानीय समय में प्रदर्शित करता है, जो दिनांक समय, समय या दिनांक के रूप में स्वरूपित होता है

टैग हेल्पर

[HtmlTargetElement("datetime", Attributes = "format,value")]
public class DateTimeTagHelper : TagHelper {

    [HtmlAttributeName("format")]
    public DateTimeFormat Format { get; set; }

    [HtmlAttributeName("value")]
    public DateTime Value { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output) {

        output.TagName = "span";
        output.TagMode = TagMode.StartTagAndEndTag;

        output.Attributes.Add("class", "datetime_init");
        output.Attributes.Add("format", Format);
        output.Attributes.Add("value", Value.ToString("u"));

    }
}

जावास्क्रिप्ट (moment.js की आवश्यकता है लेकिन अवधारणा के लिए अप्रासंगिक है)

$(document).ready(function () {
    DateTime_Init();
}

function DateTime_Init() {
    $(".datetime_init").each(function () {
        var utctime = $(this).attr("value");
        var localTime = moment.utc(utctime).toDate();

        switch($(this).attr("format")) {
            case "Date":
                $(this).html(moment(localTime).format('DD/MM/YYYY'));
                break;
            case "Time":
                $(this).html(moment(localTime).format('HH:mm'));
                break;
            default:
                $(this).html(moment(localTime).format('DD/MM/YYYY HH:mm'));
                break;
        }

        //Ensure this code only runs once
        $(this).removeClass("datetime_init");
    });
}




tag-helpers