将 JavaScript 放在部分视图中可以吗

我正在开发一个 web 应用程序,其中主页包含两部分: 常量块(总是可见)和信息块(由3个部分视图之一组成)。每个部分视图都作为 AJAX 请求的结果出现,并且只加载一次(在 jquery 提供切换窗口之后)。效果不错,但我遇到了一个问题。

部分视图的 html 代码包含常量块和 info-block 中使用的 js 函数。当加载页面时,这些函数可以“看到”对方,它可以工作,但 resharper 无法找到函数声明并提醒我这一点。我不能解决这个问题,把他们转移到外部 js 文件,因为剃刀的语法,可以在他们的代码中找到。

我能用这个做什么?

谢谢。

更新:

最后,我决定解决将 js 代码与视图分离的问题。因此,新的问题是如何在 js 文件中包含剃刀语法,或者什么是可以接受的替代方案。我找到的流行解决方案是使用全局变量、数据属性和我更喜欢的一个—— John Katsiotis 的 RazorJS 库。

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

我希望它能稳定工作,让 Resharper 高兴。

干杯!

更新:

三年后,我想起了这个问题,并决定根据我的经验更新它。事实上,现在我不建议为此使用其他库。特别是如果你不是项目团队中唯一的成员... ... 如果你在所有的库中都能得到保证,那就更好了,因为它们得到了创建者和社区的支持,并且可以很容易地集成到 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>
101621 次浏览

如果 Resharper 警告你,这没什么大不了的 ^ _ ^

但是如果我是你,我就不会把 JavaScript 放在局部视图中。

因为部分视图可以多次插入到一个页面中,那么您的 JavaScript 就会出现问题。

对于您的情况,如果您不能将 JavaScript 分离到 JS 文件,那么只需要 创建另一个 PartialView,并将这些脚本放入其中,然后在主页中呈现它。

我同意 Wahid 的观点,即不应该在视图中放入 JavaScript,无论是部分还是其他方面。我见过很多这样做的代码,知道它只会导致没有好处。

我还想说的是,您应该能够将 Razor 语法中封装的逻辑传递到 JavaScript 中,您只需要将您的逻辑所需的信息传递给 JavaScript 即可。

我只是根据下面这个注释的经验来猜测,但是你应该像设计 C # 或者 VB.NET 代码的结构一样来设计 JavaScript。这样,使用 Razor 的逻辑应该成为 JavaScript 的一部分。

这样,您的 JavaScript 将更容易维护,而且我认为 Resharper 也应该更快乐。

我这样做,发现它非常方便。使用 ViewBag、 HttpContext 等可用性动态加载部分 javascript 代码片段效果很好。

它的结果类似于使用 T4模板。

如果你像这样添加幻像脚本标签,你甚至可以得到 javascript 验证、智能感知等等。

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

如果您想编写封装了“小部件”的部分视图,只要在页面中包含它们就可以工作,那么在部分视图中嵌入一个脚本块是将标记和初始化脚本封装在一个部分视图中的一种简单方法。例如,我可能有一个名为“ _ EventList”的部分视图,我在整个站点中使用它。如果我把它放在母版页面的两个位置,它应该可以正常工作,而且我不希望在母版页面中编写逻辑来初始化小部件。

如果您在一个页面中不会使用它超过一次,那么它很简单。但是如果可能的话,那么包装脚本,这样它就不会执行两次。请看下面。为了使用 Stack Overflow 代码片段,我通过在代码片段中重复两次部分视图来模拟它,以表示在母版页中包含两次部分视图。

我的主页可能看起来像:

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

对于这个问题的未来观众,以下是我的经验。我认为将只由部分使用的脚本保留在部分中用于组织是一个好主意。

我遇到的问题是在调试期间,我有时会遇到命中断点的困难,而且除非我将脚本移动到父视图,否则无法对问题进行故障排除。很可能是由于打印该函数不止一次。我希望章节能够更好地解决和组织这个问题,但是部分视图不支持章节(至少在 MVC 4中不支持)。

所以我的回答是为了维护和调试,没有脚本不应该放在部分视图中。