Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
144 views
in Technique[技术] by (71.8m points)

c# - Javascript in a View Component

I have a View Component that contains some jQuery in the Razor (.cshtml) file. The script itself is quite specific to the view (deals with some some configuration of third-party libraries), so I would like to keep the script and HTML in the same file for organization's sake.

The problem is that the script is not rendered in the _Layout Scripts section. Apparently this is just how MVC handles scripts with regards to View Components.

I can get around it by just having the scripts in the Razor file, but not inside of the Scripts section.

But then I run into dependency issues - because jQuery is used before the reference to the library (the reference to the library is near the bottom of the _Layout file).

Is there any clever solution to this other than including the reference to jQuery as part of the Razor code (which would impede HTML rendering where ever the component is placed)?

I'm currently not in front of the code, but I can certainly provide it once I get the chance if anyone needs to look at it to better understand it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

What I decided to do is write a ScriptTagHelper that provides an attribute of "OnContentLoaded". If true, then I wrap the inner contents of the script tag with a Javascript function to execute once the document is ready. This avoids the problem with the jQuery library having not loaded yet when the ViewComponent's script fires.

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

example usage within a ViewComponent:

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

There might be a better way than this, but this has worked for me so far.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...