2017-06-13 10 views
4

Razor(.cshtml)ファイルにjQueryを含むViewコンポーネントがあります。スクリプト自体は、ビュー(サードパーティ製のライブラリのいくつかの設定を扱う)に非常に特有なので、スクリプトとHTMLを組織のために同じファイルに保存したいと思います。ViewコンポーネントのJavascript

問題は、スクリプトが_Layout Scriptsセクションに表示されないことです。明らかに、Viewコンポーネントに関するスクリプトはhow MVC handlesです。

私は、カミソリファイルにが、スクリプト部分の内部ないをスクリプトを持つことによってそれを回避することができます。

しかし、jQueryはライブラリへの参照の前に使用されています(ライブラリへの参照は_Layoutファイルの一番下にあります)。

Razorコードの一部としてjQueryへの参照を含めること以外は、賢明な解決策がありますか(これまでコンポーネントが配置されている場所でHTMLのレンダリングが妨げられるでしょうか?

私は現在、コードの前にいませんが、誰かがそれをよりよく理解するために見なければならない場合、私は確かにそれを提供することができます。

答えて

0

セクションのみ(Default.cshtmlは独立して、メインViewResultとそのLayout値の実行デフォルトでnullです。)部分図またはビュー コンポーネントでは動作しませんビューで作業し、それがでます設計。

あなたはpartial viewまたはview component'sビューを宣言Layoutためrender sectionsにそれを使用することができます。ただし、パーシャルおよびビューコンポーネントで定義されたセクションは、レンダリングビューまたはレイアウトに戻って流れません。 部分ビューまたはビューコンポーネントでjQueryまたはその他のライブラリ参照を使用する場合は、Layoutページのbodyではなく、ライブラリをheadにプルすることができます。

例:

ビューコンポーネント:ViewComponentの

public class ContactViewComponent : ViewComponent 
{ 
    public IViewComponentResult Invoke() 
    { 
     return View(); 
    } 
} 

場所:

/Views/[CurrentController]/Components/[NameOfComponent]/Default.cshtml 
/Views/Shared/Components/[NameOfComponent]/Default.cshtml 

Default.cshtml:

@model ViewComponentTest.ViewModels.Contact.ContactViewModel 

<form method="post" asp-action="contact" asp-controller="home"> 
    <fieldset> 
     <legend>Contact</legend> 
     Email: <input asp-for="Email" /><br /> 
     Name: <input asp-for="Name" /><br /> 
     Message: <textarea asp-for="Message"></textarea><br /> 
     <input type="submit" value="Submit" class="btn btn-default" /> 
    </fieldset> 
</form> 

_Layout.cshtml

<!DOCTYPE html> 
    <html> 
    <head> 
    ... 
     @RenderSection("styles", required: false) 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> 
    </head> 
    <body> 
     @RenderBody() 
    ... 
    //script move to head 
     @RenderSection("scripts", required: false) 
    </body> 
    </html> 

ビュー。CSHTML:grahamehornerによって

@{ 
    Layout = "~/Views/Shared/_Layout.cshtml";  
} 
.................. 
@{Html.RenderPartial("YourPartialView");} 
.................. 
@await Component.InvokeAsync("Contact") 
.................. 
@section Scripts { 
    <script> 
    //Do somthing 
    </script> 
} 

ビューコンポーネント:(することができますより多くの情報here)スクリプトがViewComponentにレンダリングされません@sectionは、ビューコンポーネント が能力を持っている必要があり

@section内にスクリプトを含めると、 partitalビューとは異なり、多くのビューでコンポーネントが再利用され、 コンポーネントが独自の機能を担当します。

2

「OnContentLoaded」の属性を提供するScriptTagHelperを作成しました。 trueの場合、スクリプトタグの内部コンテンツをJavascript関数でラップして、ドキュメントの準備が整ったら実行します。これにより、ViewComponentのスクリプトが起動したときにjQueryライブラリがまだロードされていないという問題が回避されます。

[HtmlTargetElement("script", Attributes = "on-content-loaded")] 
    public class ScriptTagHelper : TagHelper 
    { 
     /// <summary> 
     /// Execute script only once document is loaded. 
     /// </summary> 
     public bool OnContentLoaded { get; set; } = false; 

     public override void Process(TagHelperContext context, TagHelperOutput output) 
     { 
     if (!OnContentLoaded) base.Process(context, output); 

     var content = output.GetChildContentAsync().Result; 
     var javascript = content.GetContent(); 

     var sb = new StringBuilder(); 
     sb.Append("document.addEventListener('DOMContentLoaded',"); 
     sb.Append("function() {"); 
     sb.Append(javascript); 
     sb.Append("});"); 

     output.Content.SetHtmlContent(sb.ToString()); 
     } 
    } 

ViewComponent内の使用例:

<script type="text/javascript" on-content-loaded="true"> 
    $('.button-collapse').sideNav(); 
</script> 

あり、これよりも良い方法かもしれませんが、これは今のところ私のために働いています。

関連する問題