2012-06-19 34 views
46

我正在开发Web应用程序,其中主页面包含两部分:始终可见的常量块和由3个部分视图中的一个构成的信息块。每个局部视图都是AJAX请求的结果,并且只加载一次(在jQuery提供切换窗口之后)。它运行良好,但我遇到了一个问题。是否可以在部分视图中放入JavaScript

部分视图的html代码包含常量块和信息块中使用的js函数。当页面被加载时,这些函数可以“看到”对方,它的工作原理,但resharper无法找到函数声明,并警告我这一点。由于可以在代码中找到剃刀语法,我无法通过将它们转移到外部js文件来解决问题。

我该怎么办?

谢谢。

更新:

最后我决定从解决意见分开我的js代码的问题。所以,新的问题是如何将剃刀语法包含到js文件中或者可接受的替代方法是什么。我发现的流行解决方案是使用全局变量,数据属性和我更喜欢的一个 - John Katsiotis的RazorJS库。

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

我希望它会工作稳定做出ReSharper的快乐。

干杯!

更新:

3年后我回忆起了这个问题,并决定根据我的经验来更新它。事实上,现在我宁愿不建议使用额外的库。特别是如果你不是项目团队中唯一的成员......如果你在所有的库中都能得到保证,这会更好,它们受创建者和社区的支持,并且可以很容易地集成到你的IDE中(例如,如果使用特殊的语法) 。同样,来自团队的所有人都应该知道它是如何工作的。所以现在我建议做下一件事情:

  1. 把所有的JS保存在单独的文件中。尽可能地隔离它。 为其提供外部API。
  2. 从视图中调用API函数。
  3. 将所有Razor生成的URL,短信,常量作为资源参数传递。

例如:

js文件:

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

查看:

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

我不能决定什么答案是更有用的我:) – Tomy

+0

感谢和欢迎到Stackoverflow :) –

+0

这是一个愉快的开始这样一个不错的接待,非常感谢! – Tomy

回答

27

如果ReSharper的警告您这不是什么大不了的^ _^

但如果我是你,我不会把JavaScript放入部分视图在所有

由于部分视图可能会多次插入到一页中,因此您会在JavaScript中遇到问题。

对于您的情况,如果您无法将JavaScript分离为JS文件,那么只需即可创建另一个PartialView,并将这些脚本放入其中并将其呈现在主页面中。

+0

谢谢,瓦希德! 但有时候Resharper代码真的比我更好:) 事实上,我知道将js放入部分视图并不是一个好主意。但正如我所说,在我的网页上,它们存在于一个副本中,所以例如嵌套只是“不可能的”。 遵循你关于脚本部分视图的建议,我将使主视图非常好。但遗憾的是RenderPartial没有解决Resharper问题。我可以错了吗? – Tomy

+3

如果这是一个小应用程序,并且您不想花费更多时间,那么请保持您的工作。但是如果你在谈论“编程习惯”,那么你应该将你的JavaScript和Views分开。 –

+0

对于'@ Html.ActionLink(...)'有很多解决方案,但不是将JavaScript直接放在PartialView中。你可以看看这个答案http://stackoverflow.com/a/3789959/105445 –

3

我同意瓦希德,你不应该把JavaScript放在所有部分或其他地方的视图中。我见过足够的代码,知道它只会导致不好的结果。

我也会说你应该能够将Razor语法封装的逻辑转换成JavaScript,你只需要将你的逻辑所需的信息传递给你的JavaScript。

我只是从下次评论的经验中猜测出来的,但是您应该像设计C#或VB.NET代码的结构一样设计JavaScript。这样,你使用Razor的逻辑应该是你的JavaScript的一部分。

这样你的JavaScript会更容易维护,我认为Resharper也应该更快乐。

+0

感谢您的回答! 但问题不在于逻辑。我使用Razor来建立链接(例如Url.Action)和类似的东西。把它们作为参数传递给我看起来很奇怪。 – Tomy

+0

对于链接,您仍然可以将它们放在href上,只需使用preventDefault。此外,html5数据属性在这些情况下也很有用。看看dojo或yui3,看看这些库是如何构建的。 – eaglestorm

+0

有用的功能,谢谢! – Tomy

1

我这样做,发现它非常方便。它可以很好地动态加载部分JavaScript代码片段的可用性ViewBag,HttpContext等。

它导致感觉像使用T4模板。

如果您添加像这样的幻影脚本标签,您甚至可以获得JavaScript验证,智能感知等。

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

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

如果你想写一个封装“小工具”,只是工作,一旦你将它们包含在一个页面,然后嵌入局部视图内的脚本块局部视图是一个干净的方式来包装标记和初始化脚本在局部视图中一起使用。例如,我可能会在我的网站中使用名为“_EventList”的部分视图。如果我在我的母版页上放置两个地方,它应该只是工作,我不想在我的母版页中编写逻辑来初始化小部件。

如果你永远不会在页面中多次使用它,它很简单。但是,如果你可能,然后包装脚本,使其不会执行两次。见下文。为了堆栈溢出片段,我通过在代码片段中重复部分视图两次来模拟它,以表示在母版页中包含两次局部视图。

我的母版页可能看起来像:

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

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

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

例子:

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

+1

尽管事实上有更多upvoted的答案,我只是建议这个aproach,而不是分裂高度凝聚力的依赖关系,只是为了通过扩展对它们进行分组。所以,是我的一个大++。 –

+0

我非常赞同:不要拆分HTML和JS。毫无疑问......但是你的示例局部视图不适用于ASP MVC的Visual Studios模板的所有消费者:内部'_Layout.cshtml' jQuery在*'@RenderBody()'后面呈现,所以你不能使用它。你的解决方法并不是更好:第一行''将包含jQuery两次或更多次(每个局部视图1次,你在'_Layout.cshtml'中1次' ) – Marcel

+0

@Marcel - 该示例旨在在代码段编辑器中运行,以显示该技术。我实际上已经警告过,包括多个jQuery包含在我的回答中并提出了改进建议,所以我不确定你是否阅读了我的“免责声明”。我真正的布局页面通常在头部有jQuery和其他脚本。额外的工作超出了当时我的答案的范围/时间要求。只要它仍然在Stack Overflow中运行,欢迎您改进此答案 – codenheim

相关问题