programing

레이저 뷰 엔진이 장착된 ASP.NET MVC 3의 부분 뷰에서 특정 섹션으로 컨텐츠 주입

mailnote 2023. 7. 5. 20:55
반응형

레이저 뷰 엔진이 장착된 ASP.NET MVC 3의 부분 뷰에서 특정 섹션으로 컨텐츠 주입

에 이 ._Layout.cshtml

@RenderSection("Scripts", false)

보기에서 쉽게 사용할 수 있습니다.

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

제가 고민하는 것은 부분적인 관점에서 이 섹션 안에 어떤 콘텐츠를 삽입할 수 있는지입니다.

이것이 내 보기 페이지라고 가정해 보겠습니다.

@section Scripts { 

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

<div>
    poo bar poo
</div>

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

안에 .Scripts에서 르▁from까지의 구간_myPartial편견

어떻게 해야 하나요?

섹션은 부분 뷰에서 작동하지 않으며 이는 설계에 의한 것입니다.일부 사용자 지정 도우미를 사용하여 유사한 동작을 수행할 수도 있지만, 솔직히 필요한 스크립트를 포함하는 것은 보기의 책임이지 부분의 책임이 아닙니다.저는 스크립트에 대해 부분적으로 걱정하지 않고 메인 뷰의 @scripts 섹션을 사용하는 것을 추천합니다.

이것은 꽤 인기 있는 질문이기 때문에, 저는 제 해결책을 게시할 것입니다.

저도 같은 문제를 겪었고, 이상적이지는 않지만, 실제로 꽤 잘 작동하고 부분적으로 시각에 의존하지 않는다고 생각합니다.

제 시나리오는 작업 자체에 액세스할 수 있을 뿐만 아니라 보기, 즉 구글 맵에 포함될 수도 있다는 것이었습니다.

내 안에서_layout소유자:

@RenderSection("body_scripts", false)

내 안에서index내가 가진 보기:

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

내 안에서clientsView I have( 가 가지고 있음 html):html):

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

나의Clients_Scriptsview에는 페이지에 렌더링할 Javascript가 포함되어 있습니다.

이렇게 하면 스크립트가 분리되고 필요한 경우 페이지로 렌더링할 수 있습니다.body_scripts태그는 레이저 뷰 엔진이 발견한 첫 번째 경우에만 렌더링됩니다.

이를 통해 모든 것을 분리할 수 있습니다. 이 솔루션은 저에게 매우 효과적이며 다른 사용자들이 문제가 있을 수 있지만 "설계상" 문제를 해결할 수 있습니다.

이 스레드의 솔루션에서 사용 중인 블록 내에서 html(스크립트) 렌더링을 지연시킬 수 있는 다음과 같은 너무 복잡할 수 있는 솔루션을 참조하십시오.

사용.

"섹션"을 작성합니다.

  1. 일반적인 시나리오:부분 보기에서는 페이지에서 부분 보기가 반복되는 횟수에 관계없이 블록을 한 번만 포함합니다.

    @using (Html.Delayed(isOnlyOne: "some unique name for this section")) {
        <script>
            someInlineScript();
        </script>
    }
    
  2. 부분 뷰에서 부분을 사용할 때마다 블록을 포함합니다.

    @using (Html.Delayed()) {
        <b>show me multiple times, @Model.Whatever</b>
    }
    
  3. 몇한.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>
    }
    

섹션 렌더링

(즉, 지연된 섹션을 상위 뷰에 표시)

@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`

코드

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


}

몇 가지를 실행해야 하는 합법적인 필요성이 있는 경우js에서.partial네가 할 수 있는 방법은 다음과 같아,jQuery필수 항목:

<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>

OP의 목표는 인라인 스크립트를 자신의 부분 보기에 정의하려는 것입니다. 이 스크립트는 해당 부분 보기에만 한정되어 있으며, 해당 블록을 자신의 스크립트 섹션에 포함시키는 것으로 가정합니다.

나는 그가 부분적인 견해가 자제되기를 원한다는 것을 이해합니다.이 아이디어는 Angular를 사용할 때 구성 요소와 유사합니다.

내 방법은 스크립트를 부분 보기 내부에 그대로 유지하는 것입니다.문제는 부분 보기를 호출할 때 다른 모든 스크립트(일반적으로 레이아웃 페이지 하단에 추가됨)보다 먼저 스크립트를 실행할 수 있다는 것입니다.이 경우에는 부분 보기 스크립트가 다른 스크립트를 기다립니다.이 작업에는 여러 가지 방법이 있습니다.전에 것 중 은 제가전사던가장간것단것사다입니용는에 를 사용하는 입니다.body.

제 레이아웃 아래에는 다음과 같은 것이 있습니다.

// 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>

그런 다음 내 부분 보기(하단)에서:

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

      // .. do your thing here

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

또 다른 솔루션은 스택을 사용하여 모든 스크립트를 푸시하고 마지막에 각 스크립트를 호출하는 것입니다.이미 언급한 다른 솔루션은 Require입니다.JS/AMD 패턴도 아주 잘 작동합니다.

방해가 되지 않는 원칙에 따라 "_myPartial"이 스크립트 섹션에 직접 컨텐츠를 주입할 필요는 없습니다.이러한 부분 보기 스크립트를 별도로 추가할 수 있습니다..js파일을 저장하고 상위 뷰에서 @prefix 섹션으로 참조합니다.

특히 MVC를 사용할 때 우리가 웹에 대해 생각하는 방식에는 근본적인 결함이 있습니다.이 결함은 JavaScript가 보기의 책임이라는 것입니다.보기는 보기이고, JavaScript(동작 또는 기타)는 JavaScript입니다.Silverlight 및 WPF의 MVVM 패턴에서 우리는 "먼저 보기" 또는 "모델 우선"에 직면하게 됩니다.MVC에서 우리는 항상 모델의 관점에서 추론하려고 노력해야 하며 JavaScript는 여러 면에서 이 모델의 일부입니다.

저는 AMD 패턴을 사용하는 것을 제안하고 싶습니다 (저 자신도 Require를 좋아합니다).JS). 모듈에서 JavaScript를 분리하고, 기능을 정의한 후 JavaScript를 로드하는 뷰에 의존하는 대신 JavaScript에서 html에 연결합니다.이것은 당신의 코드를 정리하고, 당신의 걱정을 분리하고, 삶을 한 번에 쉽게 만들 것입니다.

이것은 제가 같은 파일에서 부분 보기를 위해 자바스크립트와 html을 공동으로 찾을 수 있게 해주었습니다.html과 관련된 부분을 동일한 부분 보기 파일에서 볼 수 있도록 생각 프로세스를 도와줍니다.


"_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" } })

 }

부분 보기 파일에서

@model SomeType

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

@if (region == "HTMLSection")
{


}

@if (region == "ScriptSection")
{
        <script type="text/javascript">
    </script">
}

제가 생각할 수 있는 첫 번째 해결책은 ViewBag을 사용하여 렌더링해야 하는 값을 저장하는 것입니다.

단 한 가지, 저는 이 작업이 부분적인 관점에서 작동한다면 시도해 본 적이 없지만, 그렇게 해야 합니다.

부분 뷰에서 섹션을 사용할 필요가 없습니다.

부분 보기에 포함합니다.jQuery가 로드된 후 기능을 실행합니다.코드에 대한 조건 절을 변경할 수 있습니다.

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

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

훌리오 스페더

다음 확장 방법을 사용할 수 있습니다. (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);
                }
            }
        }
    }
}

다음과 같이 사용:

partial 예제: (_MyPartial.cshtml) if에 html을 넣고, other에 js를 넣습니다.

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

_Layout.cshtml 또는 partials의 스크립트를 렌더링할 위치에 다음을 한 번만 입력합니다.이 위치에서 현재 페이지의 모든 부분의 Javascript만 렌더링합니다.

@{ Html.RenderPartialScripts(); }

그런 다음 부분을 사용하려면 다음과 같이 하십시오.이 위치에서는 html만 렌더링합니다.

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

플루토의 아이디어를 더 좋은 방법으로:

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

보기\web.config:

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

보기:

@PartialWithScripts("_BackendSearchForm")

부분(_BackendSearchForm.cshtml):

@{ RenderScriptsInBasePage(scripts()); }

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

레이아웃 페이지:

@RenderSection("scripts", required: false)

부분 뷰에 섹션을 삽입하는 방법이 있지만, 예쁘지는 않습니다.상위 뷰에서 두 변수에 액세스할 수 있어야 합니다.부분 뷰의 목적 중 일부는 해당 섹션을 만드는 것이므로 이러한 변수가 필요합니다.

부분 뷰에 섹션을 삽입하는 방법은 다음과 같습니다.

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

페이지에 부분 보기 삽입...

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

또한 이 기법을 사용하여 모든 클래스에서 섹션의 내용을 프로그래밍 방식으로 정의할 수 있습니다.

맛있게 드세요!

를 사용하면 Mvc Core를 수 .scripts아래와 같이이것은 쉽게 변형될 수 있습니다.section이름을 지정하거나 파생된 유형에서 이름을 가져온 태그입니다.은 다에대주을설합니다정에 대해 .IHttpContextAccessor.

스크립트를 추가할 때(예: 부분)

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

스크립트를 출력할 때(예: 레이아웃 파일)

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

코드

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

저는 오늘 이 문제를 겪었습니다.다음을 사용하는 해결 방법을 추가합니다.<script defer>다른 답들이 언급하는 것을 보지 못했기 때문에.

//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 :)

위의 코드는 제가 이 질문에 대해 작성한 빠른 게시물에서 발췌한 것입니다.

저는 이 문제를 완전히 다른 경로로 해결했습니다(급해서 새로운 HtmlHelper를 구현하고 싶지 않았기 때문입니다).

저는 저의 부분적 견해를 다음과 같은 큰 if-else 문장으로 마무리했습니다.

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

그런 다음 사용자 지정 ViewData를 사용하여 Partial을 두 번 호출했습니다.

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

@section scripts{
    @Html.Partial("MyPartialView", Model, 
        new ViewDataDictionary { { "ShouldRenderScripts", true } })
}

비슷한 문제가 있었는데, 마스터 페이지가 다음과 같습니다.

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

...

@Html.Partial("_Charts", Model)

그러나 부분 보기는 스크립트 섹션의 일부 JavaScript에 의존했습니다.부분 뷰를 JSON으로 인코딩하여 JavaScript 변수에 로드한 다음 이를 사용하여 div를 채우는 방법으로 해결했습니다.

@{
    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>

선택적으로 Folder/index.cshtml을 마스터 페이지로 사용한 다음 섹션 스크립트를 추가할 수 있습니다.그런 다음 레이아웃에 다음이 있습니다.

@RenderSection("scripts", required: false) 

및 인덱스.cshtml:

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

그리고 그것은 당신의 모든 부분적인 견해에 작용할 것입니다.나한테 효과가 있어요.

제 해결책은 레이아웃 페이지에서 스크립트를 로드하는 것이었습니다.그런 다음 JavaScript에서 부분 뷰에 요소 중 하나가 있는지 확인합니다.요소가 있는 경우 Javascript는 부분이 포함되었음을 알고 있습니다.

$(document).ready(function () {
    var joinButton = $("#join");
    if (joinButton.length != 0) {
        // the partial is present
        // execute the relevant code
    }
});

글쎄요, 다른 포스터들은 (제3자 html 도우미를 사용하여) 당신의 파트 내에 @ 섹션을 직접 포함시킬 수 있는 수단을 제공했다고 생각합니다.

하지만, 만약 당신의 스크립트가 당신의 부분과 밀접하게 연결되어 있다면, 당신의 부분 에 있는 인라인 태그 안에 당신의 자바스크립트를 직접 넣고 그것을 끝내라 (단일 보기에서 부분을 두 번 이상 사용할 의도가 있다면, 단지 스크립트 중복을 조심하라);

_contact.cshtml이라는 부분 보기를 사용한다고 가정하면 연락처는 합법적인(이름) 또는 실제 주체(이름, 성)일 수 있습니다.당신의 뷰는 무엇이 렌더링되고 자바스크립트로 보관될 수 있는지에 대해 주의해야 하므로 지연된 렌더링과 JS 내부 뷰가 필요할 수 있습니다.

제가 생각하는 유일한 방법은, 어떻게 그것이 생략될 수 있는지, 우리가 그러한 UI 문제를 처리하는 방해가 되지 않는 방법을 만드는 것입니다.

또한 MVC 6에는 소위 View 구성 요소가 있을 것이며, MVC 미래에도 유사한 요소가 있으며, Telerik도 이러한 요소를 지원합니다.

저는 방금 이 코드를 부분적으로 추가하여 문제를 해결했지만, 그다지 깨끗하지는 않지만 작동합니다.렌더링할 개체의 ID를 확인해야 합니다.

<script>
    $(document).ready(function () {
        $("#Profile_ProfileID").selectmenu({ icons: { button: 'ui-icon-circle-arrow-s' } });
        $("#TitleID_FK").selectmenu({ icons: { button: 'ui-icon-circle-arrow-s' } });
        $("#CityID_FK").selectmenu({ icons: { button: 'ui-icon-circle-arrow-s' } });
        $("#GenderID_FK").selectmenu({ icons: { button: 'ui-icon-circle-arrow-s' } });
        $("#PackageID_FK").selectmenu({ icons: { button: 'ui-icon-circle-arrow-s' } });
    });
</script>

저는 이것으로 비슷한 문제를 해결했습니다.

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

그것은 추측을 주입하는 좋은 방법입니다.

언급URL : https://stackoverflow.com/questions/7556400/injecting-content-into-specific-sections-from-a-partial-view-asp-net-mvc-3-with

반응형