简体   繁体   English

将JavaScript放在部分视图中是否可以

[英]Is it OK to put JavaScript in Partial Views

I'm working on the web app where the main page contains two parts: the constant block which is always visible and the info-block made up by one of 3 partial views. 我正在使用Web应用程序,其中主页面包含两个部分:始终可见的常量块和由3个部分视图之一组成的信息块。 Each of the partial views appears as a result of AJAX request and is loaded just once (after that switching windows is provided by jquery). 每个部分视图都作为AJAX请求的结果出现,并且只加载一次(在jquery提供切换窗口之后)。 It works well but I've faced with one problem. 它运作良好,但我遇到了一个问题。

The html-code of partial views contains js functions that are used in the constant block and in the info-block as well. 部分视图的html代码包含在常量块和info-block中使用的js函数。 When the page is loaded, these functions can “see” each other and it works but resharper can't find function declarations and warn me about this. 当页面加载时,这些函数可以“看到”彼此并且它可以工作,但是resharper找不到函数声明并警告我这一点。 I can't solve the problem by transferring them into external js file because of razor syntax which can be found in their code. 我无法通过将它们转移到外部js文件来解决问题,因为razor语法可以在他们的代码中找到。

What can I do with this? 我该怎么办?

Thanks. 谢谢。

Update: 更新:

Finally I've decided to solve the problem separating my js code from views. 最后,我决定解决将js代码与视图分离的问题。 So the new question was how to include razor syntax into js files or what is the acceptable alternative. 所以新的问题是如何将razor语法包含到js文件中或者什么是可接受的替代方案。 The popular solutions I've found are using global variables, data attributes and the one I like more – RazorJS library by John Katsiotis. 我发现的流行解决方案是使用全局变量,数据属性和我更喜欢的解决方案 - John Katsiotis的RazorJS库。

http://djsolid.net/blog/razorjs---write-razor-inside-your-javascript-files http://djsolid.net/blog/razorjs---write-razor-inside-your-javascript-files

I hope it's going to work stable and make Resharper happy. 我希望它能够稳定运行并使Resharper感到高兴。

Cheers! 干杯!

Update: 更新:

After 3 years I recalled this question and decided to update it according to my experience. 3年后,我回忆起这个问题,并决定根据我的经验对其进行更新。 In fact now I would rather not recommend using additional libraries for that. 事实上,现在我宁愿不建议使用额外的库。 Especially if you are not the only member in the project team… It is much better if you are ensured in all of your libraries, they are supported by creator and community and can be easily integrated into your IDE (if use special syntax for example). 特别是如果您不是项目团队中唯一的成员......如果您在所有库中得到保证,它们会受到创建者和社区的支持,并且可以轻松集成到您的IDE中(例如,如果使用特殊语法) 。 Also all the guys from your team should be aware of how does it work. 你的团队中的所有人都应该知道它是如何工作的。 So now I would suggest doing the next things: 所以现在我建议做下面的事情:

  1. Hold all the JS in separate files. 将所有JS保存在单独的文件中。 Isolate it as much as you can. 尽可能地隔离它。 Provide the external API for it. 为它提供外部API。
  2. Call the API functions from your Views. 从您的视图中调用API函数。
  3. Pass all the Razor generated URLs, text messages, constants as resource parameter. 将所有Razor生成的URL,文本消息,常量作为资源参数传递。

For example: 例如:

js file: js文件:

$.api.someInitFunction = function(resources){ ... }

View: 视图:

<script>
    $.api.someInitFunction({
        urls: { myAction: '@Url.Action("MyAction", "MyController")' },
        messages: { error: '@errorMessage' },
        consts: { myConst: @myIntConst }
    });
</script>

If Resharper warns you it's not a big deal ^_^ 如果Resharper警告你这不是什么大问题^ _ ^

But if I were you I wouldn't put JavaScript in the partial view at all . 但如果我是你,我根本不会把JavaScript放在局部视图中

Because the partial view could be inserted in one page many times then you'll get an issues with your JavaScripts. 由于部分视图可以多次插入一个页面,因此您将遇到JavaScripts问题。

And for your case if you couldn't separate the JavaScript to JS file then just create another PartialView and put these scripts in it and just render it in your main page. 对于你的情况,如果你不能将JavaScript分成JS文件,那么只需创建另一个PartialView并将这些脚本放入其中,然后在主页面中呈现它。

If you want to write partial views that are encapsulated "widgets" that just work once you include them in a page, then embedding a script block inside the partial view is one clean way to wrap the markup and the initialization script together in a partial view. 如果要编写封装了“小部件”的部分视图,只要将它们包含在页面中就可以工作,那么在部分视图中嵌入脚本块是将标记和初始化脚本封装在局部视图中的一种简洁方法。 For example, I might have a partial view named "_EventList" that I use throughout my site. 例如,我可能有一个名为“_EventList”的部分视图,我在整个网站中使用它。 If I place in two places on my master page it should just work and I prefer not to have to write logic in my master page to initialize the widget. 如果我放在我的母版页上的两个位置它应该工作,我不想在我的母版页中编写逻辑来初始化小部件。

If you will never use it more than once in a page, its simple. 如果您永远不会在页面中多次使用它,那么它很简单。 But if you might, then wrap the script so it doesn't execute twice. 但如果可能的话,请将脚本包装起来,使其不会执行两次。 See below. 见下文。 For the sake of Stack Overflow snippets I simulate it by repeating the partial view twice in the code snippet to represent including a partial view twice in a master page. 为了Stack Overflow片段,我通过在代码片段中重复两次局部视图来模拟它,以表示在母版页中包含两次局部视图。

My master page might look like: 我的母版页可能如下所示:

<div id="left-nav">
   @Html.Partial("_EventList")           
</div>

<div id="body">
</div>

<div id="right-nav">
   @Html.Partial("_EventList")
</div>

Example: 例:

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- Self-contained partial view containing widget --> <div id="widgetDiv" class="panel panel-default"> <div class="panel-heading">Event Dates</div> <div class="panel panel-group"> <ul class="widget"> <!-- These will load dynamically --> </ul> </div> <script> $(document).ready(function() { // Run this once only in case widget is on page more than once if(typeof $widget == 'undefined') { $widget = $("ul.widget"); // could be more than one // mock data to simulate an ajax call var data = [ {Description: "March", StartDate: "03/01/2015"}, {Description: "April", StartDate: "04/01/2015"}, {Description: "May", StartDate: "05/01/2015"} ]; $.each($widget, function(w, widget) { // might be an $.ajax call $.each(data, function(i, row) { $(widget).append("<li><a href='/Widget/Search?startDate=" + row.StartDate + "'>" + row.Description + "</a></li>"); }); }); } }); </script> </div> <!-- End of widget / partial view --> <!-- Second copy of above for sake of example snippet --> <!-- No need to read further --> <!-- Self-contained partial view containing widget --> <div id="widgetDiv" class="panel panel-default"> <div class="panel-heading">Event Dates</div> <div class="panel panel-group"> <ul class="tinylist nav nav-sidebar widget"> <!-- These will load dynamically --> </ul> </div> <script> $(document).ready(function() { // Run this once only in case widget is on page more than once if(typeof $widget == 'undefined') { $widget = $("ul.widget"); // could be more than one // mock data to simulate an ajax call var data = [ {Description: "March", StartDate: "03/01/2015"}, {Description: "April", StartDate: "04/01/2015"}, {Description: "May", StartDate: "05/01/2015"} ]; $.each($widget, function(w, widget) { // might be an $.ajax call $.each(data, function(i, row) { $(widget).append("<li><a href='/Widget/Search?startDate=" + row.StartDate + "'>" + row.Description + "</a></li>"); }); }); } }); </script> </div> <!-- End of widget / partial view --> 

I agree with Wahid that you shouldn't put JavaScript in views at all partial or otherwise. 我同意Wahid的观点,即你不应该在所有部分或其他方面将JavaScript放入视图中。 I've seen enough code that does this to know it only leads to no good. 我已经看到足够的代码来做到这一点,知道它只会导致无益。

I would also say that you should be able to transfer the logic encapsulated in the Razor syntax into the JavaScript, you just need to pass to your JavaScript the information needed by your logic. 我还要说你应该能够将Razor语法中封装的逻辑转移到JavaScript中,你只需要将逻辑所需的信息传递给JavaScript。

I'm just guessing from experience with this next comment but you should design the JavaScript the same way you would design the structure of your C# or VB.NET code. 我只是猜测下一条评论的经验,但你应该像设计C#或VB.NET代码的结构一样设计JavaScript。 That way the logic that you are using Razor for should be part of your JavaScript. 这样你使用Razor的逻辑应该是你的JavaScript的一部分。

That way your JavaScript will be easier to maintain and I assume Resharper should also be happier. 这样你的JavaScript将更容易维护,我认为Resharper也应该更快乐。

I do this and find it highly convenient. 我这样做,发现它非常方便。 It works well to dynamically load partial javascript snippets with the availability of ViewBag, HttpContext, etc. 它适用于动态加载部分javascript片段以及ViewBag,HttpContext等的可用性。

It results in something that feels like using T4 templates. 它产生的感觉就像使用T4模板。

You can even get javascript validation, intellisense, etc if you add phantom script tags like this. 如果你添加像这样的幻像脚本标签,你甚至可以获得javascript验证,intellisense等。

@using System.Configuration
@if (false)
{
    @:<script type="text/javascript">
}    
        $scope.clickCartItem = function(cartItem) {
            console.log(cartItem);
            window.location.href =@Html.Raw("('" + ConfigurationManager.AppSettings["baseUrl"] + "/Checkout/' + cartItem.ItemId)");
        };
        dataAccess.getCart(
        function (response) {
            //...
        },
        function (response) {
            //...
        }
        );

@if (false)
{
    @:</script>
}

For future viewers of this question, here is my experience. 对于这个问题的未来观众,这是我的经验。 I thought it would be a good idea to keep the scripts that were only used by the partial in the partial for organization. 我认为保留仅部分用于组织的部分脚本是个好主意。

The issue I had was during debugging, I sometimes would have trouble getting my breakpoints to hit and wouldn't be able to troubleshoot an issue unless I moved the script to the parent view. 我遇到的问题是在调试过程中,我有时会遇到断点而无法解决问题,除非我将脚本移到父视图中。 Most likely due to printing the function more than once. 最有可能的原因是打印功能不止一次。 I was hoping sections would solve and organize this better, but sections are not supported in partial views (at least not in MVC 4). 我希望部分能够更好地解决和组织这些部分,但部分视图中不支持部分(至少在MVC 4中不支持)。

So my answer would be for the sake of maintenance and debugging, no scripts should not be put inside partial views. 所以我的答案是为了维护和调试,不应该在部分视图中放入脚本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM