在 ASP.NET MVC 中动态生成 Javascript、CSS
Posted
技术标签:
【中文标题】在 ASP.NET MVC 中动态生成 Javascript、CSS【英文标题】:Dynamically generated Javascript, CSS in ASP.NET MVC 【发布时间】:2013-04-12 03:07:00 【问题描述】:ASP.NET 允许使用服务器标签(razor 或 ASPX)动态生成 html。但是除了使用内联(嵌入式)CSS / javascript之外,有没有什么好的方法可以以相同的方式生成 *.js 或 *.css 内容。如今,随着 Ajax 等技术的出现,越来越多的逻辑在 Javascript 中从服务器端转移到客户端。如果有机会使用 ASP.NET 为 HTML 生成提供的所有灵活性来动态生成 JS,那就太好了。
例如,我的 Javascript 包含 Knockout 视图模型声明,其中包含在 Javascript 渲染期间从服务器加载的初始数据,以及一些额外的 js 函数,所以在我的 Html 中而不是嵌入式脚本 em> 我想要这样的脚本引用:
<script src="~/Scripts/ContactViewModel.js?contactId=@Model.ContactId"></script>
另一个例子,开发者可能需要它是使用基于用户配置文件的 CSS。用户配置文件信息包含在 CSS 生成期间必须遵守的样式信息(字体、颜色,而不仅仅是主题),所以在我看来,我会有类似的内容:
<link href="~/Styles/CurrentUserOverrides.css" rel="stylesheet" />
CurrentUserOverrides.css 将根据认证用户的个人资料数据动态生成。
如何使用 ASP.NET MVC 做到这一点?我想找到一个解决方案,让我能够像使用 ASP.NET 创建动态 HTML 一样简单,同时具备正常工作的智能以及 VS 为 ASP.NET 视图提供的所有其他功能。
【问题讨论】:
我不确定我是否了解您想要完成的工作的好处。为什么要为特定页面生成上下文敏感的 Javascript? 您是否尝试使用 ContactViewModel.js 中的contactId(并且 123 的 ContactId 实际上是由您的视图模型呈现的)? 是的,ContactViewModel.js 需要用指定的 ContactId 从数据库中加载字段值来声明对象 【参考方案1】:目前我找到的最佳解决方案如下:
Dynamic Javascript and CSS in ASP.NET MVC using Razor Views
您只需创建视图:CurrentUserOverrides.css.cshtml、ContactViewModel.js.cshtml。此视图将包含单个 HTML 块(<script>
或 <style>
),因此 IntelliSense 工作正常。然后您创建控制器来呈现该视图,修剪根标记并返回具有适当内容类型的内容。
【讨论】:
【参考方案2】:CSHTML 文件中的动态 CSS
我使用 CSS cmets /* */
注释掉一个新的 <style>
标记,然后我在结束样式标记之前 return;
:
/*<style type="text/css">/* */
CSS GOES HERE
@return;</style>
CSHTML 文件中的动态 JS
我使用 JavaScript cmets <!--//
注释掉一个新的 <script>
标记,然后我在结束脚本标记之前 return;
:
//<script type="text/javascript">
JAVASCRIPT GOES HERE
@return;</script>
MyDynamicCss.cshtml
@
var fieldList = new List<string>();
fieldList.Add("field1");
fieldList.Add("field2");
/*<style type="text/css">/* */
@foreach (var field in fieldList) <text>
input[name="@field"]
, select[name="@field"]
background-color: #bbb;
color: #6f6f6f;
</text>
@return;</style>
MyDynamicJavsScript.cshtml
@
var fieldList = new List<string>();
fieldList.Add("field1");
fieldList.Add("field2");
fieldArray = string.Join(",", fieldList);
//<script type="text/javascript">
$(document).ready(function ()
var fieldList = "@Html.Raw(fieldArray)";
var fieldArray = fieldList.split(',');
var arrayLength = fieldArray.length;
var selector = '';
for (var i = 0; i < arrayLength; i++)
var field = fieldArray[i];
selector += (selector == '' ? '' : ',')
+ 'input[name="' + field + '"]'
+ ',select[name="' + field + '"]';
$(selector).attr('disabled', 'disabled');
$(selector).addClass('disabled');
);
@return;</script>
无需控制器(使用视图/共享)
我将我的两个动态脚本都放入了Views/Shared/
,我可以使用以下代码轻松地将它们嵌入到任何现有页面(或_Layout.cshtml
)中:
<style type="text/css">@Html.Partial("MyDynamicCss")</style>
<script type="text/javascript">@Html.Partial("MyDynamicJavaScript")</script>
使用控制器(可选)
如果您愿意,可以创建一个控制器,例如
<link rel="stylesheet" type="text/css" href="@Url.Action("MyDynamicCss", "MyDynamicCode")">
<script type="text/javascript" src="@Url.Action("MyDynamicJavaScript", "MyDynamicCode")"></script>
这是控制器的外观
MyDynamicCodeController.cs(可选)
[HttpGet]
public ActionResult MyDynamicCss()
Response.ContentType = "text/css";
return View();
[HttpGet]
public ActionResult MyDynamicJavaScript()
Response.ContentType = "application/javascript";
return View();
备注
控制器版本未经测试。我只是在脑海中输入的。 在重新阅读我的答案后,我突然想到,注释掉结束标记而不是使用 cshtml@return;
可能同样容易,但我还没有尝试过。我想这是一个偏好问题。
关于我的整个回答,如果您发现任何语法错误或改进,请告诉我。
【讨论】:
多么棒的答案。谢谢你。正是我所需要的。我只是不明白棘手的//
部分。你能详细说明吗?
@RoyiNamir 自动完成和颜色。在 JavaScript 示例中,Web 浏览器正在读取 JavaScript,看到 //
并忽略该行的其余部分作为 JavaScript 注释。所以网络浏览器会忽略<script>
标签。不过,Visual Studio 认为所有 cshtml 文件都是 HTML。 Visual Studio 将//
读取为纯文本以发送到浏览器,但将<script>
标记视为JavaScript 块的开头。 <script>
标记之后的所有内容都被着色为 JavaScript,您应该从自动完成中获得 JavaScript 建议。
顺便说一句 - 我已经设法做到了没有“返回”部分等:i.imgur.com/yxp52fL.jpg。所以我现在不明白@return;
部分
@return;
之后的任何内容都不会发送到浏览器。 cshtml 执行到此结束。 @
在 cshtml 视图中开始内联 C#。 return;
通常从方法或函数返回,但在这种情况下它从 cshtml 页面返回。
结束 cshtml 页面内的内联 C#。【参考方案3】:
为时已晚,但仍然很有趣,这是我的解决方案: 像这样形成你的 cshtml 调用:
<script src='@Url.Action("GetJS", "Home")'></script>
创建一个像这样生成 JS 或 CSS 的控制器方法:
public ActionResult GetJS()
byte[] jsDATA = System.Text.ASCIIEncoding.ASCII.GetBytes(mystingJS);
return File(jsDATA, "text/javascript");
【讨论】:
【参考方案4】:有一种相对较新的语言TypeScript,我认为这可能是您正在寻找的 JavaScript,而不是 CSS。 Here 是一篇让其在 ASP.NET MVC4 中工作的帖子。
【讨论】:
是的,很遗憾 TypeScript 是开箱即用的解决方案,而且还不清楚 IntelliSense 如何在那里工作。 在撰写本文时,TypeScript 开始成熟,VS 中的智能感知非常出色。虽然,我不确定这是否真的是用户要求的。以上是关于在 ASP.NET MVC 中动态生成 Javascript、CSS的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 jquery unobtrusive 和 Asp.Net Mvc 验证动态生成的单选按钮组?
如何使用jQuery unobtrusive和Asp.Net Mvc验证动态生成的单选按钮组?
ASP.Net MVC:具有动态列的 Jquery 数据表与 JSON 绑定