在 JavaScript 中使用 Razor
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4599169/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Razor within JavaScript
提问by raklos
Is it possible or is there a workaround to use Razor syntax within JavaScript that is in a view (cshtml
)?
在视图 ( cshtml
)中的 JavaScript 中使用 Razor 语法是否可能或是否有解决方法?
I am trying to add markers to a Google map... For example, I tried this, but I'm getting a ton of compilation errors:
我正在尝试向 Google 地图添加标记......例如,我尝试过这个,但我收到了大量的编译错误:
<script type="text/javascript">
// Some JavaScript code here to display map, etc.
// Now add markers
@foreach (var item in Model) {
var markerlatLng = new google.maps.LatLng(@(Model.Latitude), @(Model.Longitude));
var title = '@(Model.Title)';
var description = '@(Model.Description)';
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: latLng,
title: title,
map: map,
draggable: false
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
</script>
回答by StriplingWarrior
Use the <text>
pseudo-element, as described here, to force the Razor compiler back into content mode:
使用<text>
伪元素,如所描述这里,迫使剃刀编译器返回到内容模式:
<script type="text/javascript">
// Some JavaScript code here to display map, etc.
// Now add markers
@foreach (var item in Model) {
<text>
var markerlatLng = new google.maps.LatLng(@(Model.Latitude), @(Model.Longitude));
var title = '@(Model.Title)';
var description = '@(Model.Description)';
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: latLng,
title: title,
map: map,
draggable: false
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
</text>
}
</script>
Update:
更新:
Scott Guthrie recently postedabout @:
syntax in Razor, which is slightly less clunky than the <text>
tag if you just have one or two lines of JavaScript code to add. The following approach would probably be preferable, because it reduces the size of the generated HTML. (You could even move the addMarker function to a static, cached JavaScript file to further reduce the size):
Scott Guthrie 最近发布了关于@:
Razor 语法的文章,<text>
如果您只需要添加一两行 JavaScript 代码,Razor 会比标签稍微笨拙一些。以下方法可能更可取,因为它减少了生成的 HTML 的大小。(您甚至可以将 addMarker 函数移动到静态、缓存的 JavaScript 文件以进一步减小大小):
<script type="text/javascript">
// Some JavaScript code here to display map, etc.
...
// Declare addMarker function
function addMarker(latitude, longitude, title, description, map)
{
var latLng = new google.maps.LatLng(latitude, longitude);
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: latLng,
title: title,
map: map,
draggable: false
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
// Now add markers
@foreach (var item in Model) {
@:addMarker(@item.Latitude, @item.Longitude, '@item.Title', '@item.Description', map);
}
</script>
Updated the above code to make the call to addMarker
more correct.
更新了上面的代码,使调用addMarker
更正确。
To clarify, the @:
forces Razor back into text mode, even though addMarker
call looks a lot like C# code. Razor then picks up the @item.Property
syntax to say that it should directly output the contents of those properties.
澄清一下,@:
强制 Razor 回到文本模式,即使addMarker
调用看起来很像 C# 代码。然后 Razor 选择@item.Property
语法说它应该直接输出这些属性的内容。
Update 2
更新 2
It's worth noting that View code really isn't a good place to put JavaScript code. JavaScript code should be placed in a static .js
file, and then it should get the data that it needs either from an Ajax call or by scanning data-
attributes from the HTML. Besides making it possible to cache your JavaScript code, this also avoids issues with encoding, since Razor is designed to encode for HTML, but not JavaScript.
值得注意的是,View 代码确实不是放置 JavaScript 代码的好地方。JavaScript 代码应该放在一个静态.js
文件中,然后它应该通过 Ajax 调用或通过扫描data-
HTML 中的属性来获取它需要的数据。除了可以缓存 JavaScript 代码之外,这还避免了编码问题,因为 Razor 旨在为 HTML 编码,而不是为 JavaScript 编码。
View Code
查看代码
@foreach(var item in Model)
{
<div data-marker="@Json.Encode(item)"></div>
}
JavaScript code
JavaScript 代码
$('[data-marker]').each(function() {
var markerData = $(this).data('marker');
addMarker(markerData.Latitude, markerData.Longitude,
markerData.Description, markerData.Title);
});
回答by mpen
I just wrote this helper function. Put it in App_Code/JS.cshtml
:
我刚刚写了这个辅助函数。把它放进去App_Code/JS.cshtml
:
@using System.Web.Script.Serialization
@helper Encode(object obj)
{
@(new HtmlString(new JavaScriptSerializer().Serialize(obj)));
}
Then in your example, you can do something like this:
然后在您的示例中,您可以执行以下操作:
var title = @JS.Encode(Model.Title);
Notice how I don't put quotes around it. If the title already contains quotes, it won't explode. Seems to handle dictionaries and anonymous objects nicely too!
注意我没有在它周围加上引号。如果标题已经包含引号,它不会爆炸。似乎也能很好地处理字典和匿名对象!
回答by Adam Lassek
You're trying to jam a square peg in a round hole.
您正试图将方钉塞入圆孔中。
Razor was intended as an HTML-generating template language. You may very well get it to generate JavaScript code, but it wasn't designed for that.
Razor 旨在作为一种生成 HTML 的模板语言。您很可能会使用它来生成 JavaScript 代码,但它并不是为此而设计的。
For instance: What if Model.Title
contains an apostrophe? That would break your JavaScript code, and Razor won't escape it correctly by default.
例如:如果Model.Title
包含撇号怎么办?这会破坏您的 JavaScript 代码,并且默认情况下 Razor 不会正确转义它。
It would probably be more appropriate to use a String generator in a helper function. There will likely be fewer unintended consequences of that approach.
在辅助函数中使用字符串生成器可能更合适。这种方法的意外后果可能会更少。
回答by marcind
What specific errors are you seeing?
您看到了哪些具体错误?
Something like this could work better:
像这样的东西可以更好地工作:
<script type="text/javascript">
//now add markers
@foreach (var item in Model) {
<text>
var markerlatLng = new google.maps.LatLng(@Model.Latitude, @Model.Longitude);
var title = '@(Model.Title)';
var description = '@(Model.Description)';
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'
</text>
}
</script>
Note that you need the magical <text>
tag after the foreach
to indicate that Razor should switch into markup mode.
请注意,您需要在<text>
之后的神奇标记foreach
来指示 Razor 应切换到标记模式。
回答by SLaks
That will work fine, as long as it's in a CSHTML page and not an external JavaScript file.
只要它在 CSHTML 页面中而不是外部 JavaScript 文件中,就可以正常工作。
The Razor template engine doesn't care what it's outputting and does not differentiate between <script>
or other tags.
Razor 模板引擎并不关心它输出的是什么,也不区分<script>
其他标签。
However, you need to encode your strings to prevent XSSattacks.
但是,您需要对字符串进行编码以防止XSS攻击。
回答by Fernando JS
I prefer "<!--" "-->" like a "text>"
我更喜欢 "<!--" "-->" 就像 "text>"
<script type="text/javascript">
//some javascript here
@foreach (var item in itens)
{
<!--
var title = @(item.name)
...
-->
</script>
回答by Andy
One thing to add - I found that Razor syntax hilighter (and probably the compiler) interpret the position of the opening bracket differently:
要添加的一件事 - 我发现 Razor 语法高亮器(可能还有编译器)对左括号的位置有不同的解释:
<script type="text/javascript">
var somevar = new Array();
@foreach (var item in items)
{ // <---- placed on a separate line, NOT WORKING, HILIGHTS SYNTAX ERRORS
<text>
</text>
}
@foreach (var item in items) { // <---- placed on the same line, WORKING !!!
<text>
</text>
}
</script>
回答by raddevus
A simple and a good straight-forward example:
一个简单而直接的例子:
<script>
// This gets the username from the Razor engine and puts it
// in JavaScript to create a variable I can access from the
// client side.
//
// It's an odd workaraound, but it works.
@{
var outScript = "var razorUserName = " + "\"" + @User.Identity.Name + "\"";
}
@MvcHtmlString.Create(outScript);
</script>
This creates a script in your page at the location you place the code above which looks like the following:
这将在您的页面中在您放置上面代码的位置创建一个脚本,如下所示:
<script>
// This gets the username from the Razor engine and puts it
// in JavaScript to create a variable I can access from
// client side.
//
// It's an odd workaraound, but it works.
var razorUserName = "daylight";
</script>
Now you have a global JavaScript variable named razorUserName
which you can access and use on the client. The Razor engine has obviously extracted the value from @User.Identity.Name
(server-side variable) and put it in the code it writes to your script tag.
现在您有一个全局 JavaScript 变量razorUserName
,您可以在客户端访问和使用它。Razor 引擎显然已经从@User.Identity.Name
(服务器端变量)中提取了值,并将其放入写入脚本标记的代码中。
回答by Ice2burn
The following solution seems more accurate to me than combine JavaScript with Razor. Check this out: https://github.com/brooklynDev/NGon
以下解决方案对我来说似乎比将 JavaScript 与 Razor 结合使用更准确。看看这个:https: //github.com/brooklynDev/NGon
You can add almost any complex data to ViewBag.Ngonand access it in JavaScript
您几乎可以将任何复杂数据添加到ViewBag.Ngon并在JavaScript 中访问它
In the controller:
在控制器中:
public class HomeController : Controller
{
public ActionResult Index()
{
var person = new Person { FirstName = "John", LastName = "Doe", Age = 30 };
ViewBag.NGon.Person = person;
return View();
}
}
In JavaScript:
在 JavaScript 中:
<script type="text/javascript">
$(function () {
$("#button").click(function () {
var person = ngon.Person;
var div = $("#output");
div.html('');
div.append("FirstName: " + person.FirstName);
div.append(", LastName: " + person.LastName);
div.append(", Age: " + person.Age);
});
});
</script>
It's allows any plain old CLR objects(POCOs) that can be serialized using the default JavascriptSerializer
.
它允许任何普通的旧CLR对象可以使用默认序列化(波苏斯)JavascriptSerializer
。
回答by Tuukka Lindroos
There is also one more option than @: and <text></text>
.
除了 @: 和 ,还有一个选项<text></text>
。
Using <script>
block itself.
使用<script>
块本身。
When you need to do large chunks of JavaScript depending on Razor code, you can do it like this:
当您需要根据 Razor 代码执行大量 JavaScript 时,您可以这样做:
@if(Utils.FeatureEnabled("Feature")) {
<script>
// If this feature is enabled
</script>
}
<script>
// Other JavaScript code
</script>
Pros of this manner is that it doesn't mix JavaScript and Razor too much, because mixing them a lot will cause readability issues eventually. Also large text blocks are not very readable either.
这种方式的优点是它不会过多地混合 JavaScript 和 Razor,因为大量混合它们最终会导致可读性问题。此外,大文本块的可读性也不是很好。