如何使用 MVC4 和 Razor 设置 javascript 变量
Posted
技术标签:
【中文标题】如何使用 MVC4 和 Razor 设置 javascript 变量【英文标题】:How to set javascript variables using MVC4 with Razor 【发布时间】:2013-01-29 18:22:37 【问题描述】:有人可以格式化下面的代码,以便我可以使用 razor 使用 c# 代码设置 srcript 变量吗?
下面的方法不起作用,我知道这样做很容易让别人帮忙。
@int proID = 123; int nonProID = 456;
<script type="text/javascript">
@
<text>
var nonID =@nonProID;
var proID= @proID;
window.nonID = @nonProID;
window.proID=@proID;
</text>
</script>
我遇到了设计时错误
【问题讨论】:
“不起作用”。怎么不行? 这可能是新的,但var nonID =@(nonProID);
为我工作。
【参考方案1】:
您应该查看剃刀页面生成的输出。实际上,您需要知道server-side
和client-side
执行了什么。试试这个:
@
int proID = 123;
int nonProID = 456;
<script>
var nonID = @nonProID;
var proID = @proID;
window.nonID = @nonProID;
window.proID = @proID;
</script>
输出应该是这样的:
根据您使用的 Visual Studio 版本,它会在设计时为带有 razor 的视图指出一些亮点。
【讨论】:
在设计时,Visual Studio 说这是 sintax 错误,但它呈现正确的输出。看看我的编辑。 @FelipeOriani 将其包裹在<text/>
标签中:例如:var nonID = @nonProID<text>;</text>
。
是的,VS 会在脚本标签内给你误导性的错误,但代码可以正常工作。
你说得对,VS 会产生误导性错误。谢谢【参考方案2】:
由于在处理视图时可能会出现 razor 语法错误,因此我完全明白为什么要避免它们。这里有几个其他选项。
<script type="text/javascript">
// @Model.Count is an int
var count = '@Model.Count';
var countInt = parseInt('@Model.ActiveLocsCount');
</script>
引号充当分隔符,因此剃刀解析器很高兴。但当然,您的 C# int 在第一条语句中变成了 JS 字符串。对于纯粹主义者来说,第二种选择可能更好。
如果有人有更好的方法来做到这一点而不会出现剃刀语法错误,特别是保持 var 的类型,我很乐意看到它!
【讨论】:
对我来说这是唯一的解决方案,完美运行:D【参考方案3】:这就是我解决问题的方法:
@int proID = 123; int nonProID = 456;
<script type="text/javascript">
var nonID = Number(@nonProID);
var proID = Number(@proID);
</script>
它是自记录的,不涉及到文本的转换。
注意:小心使用 Number()
函数,不要创建 new Number()
对象 - 因为完全等于运算符的行为可能不明显:
var y = new Number(123); // Note incorrect usage of "new"
var x = new Number(123);
alert(y === 123); // displays false
alert(x == y); // displays false
【讨论】:
@hectorct 非常正确我想我必须测试过var y = new Number(123)
,因为这会产生错误。已更新答案。感谢您的提醒!【参考方案4】:
我已经看到了几种解决该错误的方法,并且我运行了一些计时测试以了解哪些方法可以提高速度 (http://jsfiddle.net/5dwwy/)
方法:
-
直接分配
在这种方法中,剃刀语法直接分配给变量。这就是引发错误的原因。作为基线,JavaScript 速度测试只是将数字直接分配给变量。
通过 `Number` 构造函数在这种方法中,我们将 razor 语法包装在对 `Number` 构造函数的调用中,就像在 `Number(@ViewBag.Value)` 中一样。
解析整数在这种方法中,剃刀语法放在引号内并传递给 `parseInt` 函数。
值返回函数在这种方法中,创建了一个函数,它简单地将剃刀语法作为参数并返回它。
类型检查功能在这种方法中,函数会执行一些基本的类型检查(基本上是查找 null),如果不为 null,则返回该值。
程序:
使用上述每种方法,for-loop
重复每个函数调用 10M 次,得到整个循环的总时间。然后,该 for 循环重复 30 次以获得每 10M 动作的平均时间。然后将这些时间相互比较,以确定哪些操作比其他操作更快。
请注意,由于是 JavaScript 运行,其他人收到的实际数字会有所不同,但重要性不在于实际数字,而是数字与其他数字的比较。
结果:
使用直接分配方法,处理 1000 万个分配的平均时间为 98.033 毫秒。使用 Number
构造函数每 10M 产生 1554.93ms。同样,parseInt
方法花费了 1404.27 毫秒。两个函数调用对于简单函数耗时 97.5ms,对于更复杂函数耗时 101.4ms。
结论:
要理解的最简洁的代码是直接赋值。但是,由于 Visual Studio 中的错误,这会报告错误,并可能导致 Intellisense 出现问题并给人一种模糊的错误感觉。
最快的代码是简单的函数调用,但只是微不足道。由于我没有做进一步的分析,我不知道这种差异是否具有统计学意义。类型检查功能也非常快,只比直接赋值稍慢,并且包括变量可能为空的可能性。不过,这并不实用,因为如果参数未定义(剃刀语法中为 null),即使是基本函数也会返回 undefined。
将 razor 值解析为 int 并通过构造函数运行它非常慢,比直接赋值慢 15 倍。很可能Number
构造函数实际上在内部调用parseInt
,这可以解释为什么它比简单的parseInt
需要更长的时间。但是,它们确实具有更有意义的优点,不需要执行外部定义的(即文件或应用程序中的其他位置)函数,Number
构造函数实际上最小化了整数到字符串的可见转换。
归根结底,这些数字是经过 10M 次迭代生成的。单品上,速度小得不可估量。对于大多数人来说,简单地通过Number
构造函数运行它可能是最易读的代码,尽管它是最慢的。
【讨论】:
这个答案太棒了。在研究性能方面做得很好。【参考方案5】:@
int proID = 123;
int nonProID = 456;
<script>
var nonID = '@nonProID';
var proID = '@proID';
window.nonID = '@nonProID';
window.proID = '@proID';
</script>
【讨论】:
【参考方案6】:一种简单的方法是:
<input type="hidden" id="SaleDateValue" value="@ViewBag.SaleDate" />
<input type="hidden" id="VoidItem" value="@Model.SecurityControl["VoidItem"].ToString()" />
然后在javascript中获取值:
var SaleDate = document.getElementById('SaleDateValue').value;
var Item = document.getElementById('VoidItem').value;
【讨论】:
这种方式适用于字符串,其他建议似乎不适用于它们。 任何类型的数据都可以通过这种方式轻松处理。它不仅仅与字符串数据类型有关。您可以再次解析JavaScript
中的数据类型。
处理 js 模块和 .net 变量的好方法。
是的,我觉得它最简单。 ;-)【参考方案7】:
我找到了一个非常干净的解决方案,它允许单独的逻辑和 GUI:
在你的 razor .cshtml 页面中试试这个:
<body id="myId" data-my-variable="myValue">
...your page code here
</body>
在您的 .js 文件或 .ts(如果您使用 typeScript)中从您的视图中读取存储的值,放置一些类似这样的内容(需要 jquery 库):
$("#myId").data("my-variable")
【讨论】:
其中 myValue 可以替换为 c# 变量:@myCSharpVariable【参考方案8】:与其说是一个警示故事,不如说是一个答案:这也困扰着我——我认为我有一个解决方案,方法是在前面加上一个零并使用 @(...)
语法。即您的代码将是:
var nonID = 0@(nonProID);
var proID = 0@(proID);
得到如下输出:
var nonId = 0123;
我没有意识到这就是 JavaScript(版本 3)表示八进制/base-8 数字的方式,并且实际上正在改变值。此外,如果您使用 "use strict";
命令,那么它将完全破坏您的代码,因为八进制数已被删除。
我仍在寻找合适的解决方案。
【讨论】:
不太了解问题,但尝试在前面加上 +【参考方案9】:如果你这样做,它会起作用:
var proID = @proID + 0;
生成的代码类似于:
var proID = 4 + 0;
确实有点奇怪,但至少没有更多虚假的语法错误。 遗憾的是,在 VS2013 中仍会报告错误,因此尚未正确解决(目前)。
【讨论】:
【参考方案10】:我一直在研究这种方法:
function getServerObject(serverObject)
if (typeof serverObject === "undefined")
return null;
return serverObject;
var itCameFromDotNet = getServerObject(@dotNetObject);
对我来说,这似乎让 JS 方面更安全......最坏的情况是你最终会得到一个空变量。
【讨论】:
【参考方案11】:这应该涵盖所有主要类型:
public class ViewBagUtils
public static string ToJavascriptValue(dynamic val)
if (val == null) return "null";
if (val is string) return val;
if (val is bool) return val.ToString().ToLower();
if (val is DateTime) return val.ToString();
if (double.TryParse(val.ToString(), out double dval)) return dval.ToString();
throw new ArgumentException("Could not convert value.");
并且在<script>
标记内的.cshtml 文件中:
@using Namespace_Of_ViewBagUtils
const someValue = @ViewBagUtils.ToJavascriptValue(ViewBag.SomeValue);
请注意,对于字符串值,您必须在单(或双)引号内使用 @ViewBagUtils
表达式,如下所示:
const someValue = "@ViewBagUtils.ToJavascriptValue(ViewBag.SomeValue)";
【讨论】:
【参考方案12】:我使用一个非常简单的function
来解决与Razor
代码混合的JavaScript
代码正文中的语法错误;)
function n(num)return num;
var nonID = n(@nonProID);
var proID= n(@proID);
【讨论】:
【参考方案13】:这会直接从 web.config 定义的 appSetting 为我设置一个 JavaScript 变量。
var pv = '@System.Web.Configuration.WebConfigurationManager.AppSettings["pv"]';
【讨论】:
【参考方案14】:有
var jsVar = JSON.parse(@Html.Raw(Json.Serialize(razorObject)));
您可以将任何 razor 对象解析为 JavaScript 对象。
它很长但很普遍
【讨论】:
以上是关于如何使用 MVC4 和 Razor 设置 javascript 变量的主要内容,如果未能解决你的问题,请参考以下文章
在 MVC4 razor 中使用“远程”验证处理多个提交按钮
C# MVC4 Razor 部分视图 - 切换视图时刷新整页?