rak*_*los 419 javascript asp.net-mvc razor
在view(cshtml
)中的JavaScript中使用Razor语法是否可行或有解决方法?
我正在尝试将标记添加到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>
Run Code Online (Sandbox Code Playgroud)
Str*_*ior 618
使用<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>
Run Code Online (Sandbox Code Playgroud)
更新:
Scott Guthrie最近发布了关于@:
Razor的语法,<text>
如果你只需添加一行或两行JavaScript代码,它就会比标签略显笨重.以下方法可能更可取,因为它减少了生成的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>
Run Code Online (Sandbox Code Playgroud)
更新了上面的代码,使调用addMarker
更加正确.
为了澄清,@:
Razor 的力量回到文本模式,即使addMarker
调用看起来很像C#代码.然后Razor选择@item.Property
语法来说它应该直接输出这些属性的内容.
值得注意的是,View代码确实不是放置JavaScript代码的好地方.JavaScript代码应放在静态.js
文件中,然后它应该从Ajax调用或扫描data-
HTML中的属性获取所需的数据.除了可以缓存JavaScript代码之外,这还避免了编码问题,因为Razor旨在编码HTML,而不是JavaScript.
@foreach(var item in Model)
{
<div data-marker="@Json.Encode(item)"></div>
}
Run Code Online (Sandbox Code Playgroud)
$('[data-marker]').each(function() {
var markerData = $(this).data('marker');
addMarker(markerData.Latitude, markerData.Longitude,
markerData.Description, markerData.Title);
});
Run Code Online (Sandbox Code Playgroud)
mpe*_*pen 40
我刚写了这个辅助函数.把它放进去App_Code/JS.cshtml
:
@using System.Web.Script.Serialization
@helper Encode(object obj)
{
@(new HtmlString(new JavaScriptSerializer().Serialize(obj)));
}
Run Code Online (Sandbox Code Playgroud)
然后在您的示例中,您可以执行以下操作:
var title = @JS.Encode(Model.Title);
Run Code Online (Sandbox Code Playgroud)
注意我怎么不在它周围加上引号.如果标题已包含引号,则不会爆炸.似乎也很好地处理字典和匿名对象!
Ada*_*sek 22
你试图把一个方形的钉子塞进圆孔里.
Razor旨在用作生成HTML的模板语言.您很可能会生成JavaScript代码,但它不是为此而设计的.
例如:如果Model.Title
包含撇号怎么办?这会破坏您的JavaScript代码,默认情况下Razor无法正确转义它.
在辅助函数中使用String生成器可能更合适.这种方法可能会产生更少的意外后果.
mar*_*ind 16
您看到了哪些具体错误?
像这样的东西可以更好地工作:
<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>
Run Code Online (Sandbox Code Playgroud)
请注意,<text>
在foreach
指示Razor应切换到标记模式后,您需要使用魔法标记.
Fer*_* JS 10
我更喜欢"<! - "" - >"喜欢"文字>"
<script type="text/javascript">
//some javascript here
@foreach (var item in itens)
{
<!--
var title = @(item.name)
...
-->
</script>
Run Code Online (Sandbox Code Playgroud)
有一点要补充 - 我发现Razor语法hilighter(可能还有编译器)以不同的方式解释了开括号的位置:
<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>
Run Code Online (Sandbox Code Playgroud)
一个简单而好的直截了当的例子:
<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>
Run Code Online (Sandbox Code Playgroud)
这会在页面中放置代码的位置创建一个脚本,如下所示:
<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>
Run Code Online (Sandbox Code Playgroud)
现在,您有一个名为的全局JavaScript变量razorUserName
,您可以在客户端上访问和使用它.Razor引擎显然从@User.Identity.Name
(服务器端变量)中提取了值,并将其放入写入脚本标记的代码中.
以下解决方案似乎比将JavaScript与Razor结合起来更准确.看看这个:https: //github.com/brooklynDev/NGon
您可以将几乎任何复杂数据添加到ViewBag.Ngon并在JavaScript中访问它
在控制器中:
public class HomeController : Controller
{
public ActionResult Index()
{
var person = new Person { FirstName = "John", LastName = "Doe", Age = 30 };
ViewBag.NGon.Person = person;
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
在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>
Run Code Online (Sandbox Code Playgroud)
它允许任何可以使用默认值序列化的普通旧CLR对象(POCO)JavascriptSerializer
.
还有一个选项比@:和<text></text>
.
使用<script>
块本身.
当您需要根据Razor代码执行大量JavaScript时,您可以这样做:
@if(Utils.FeatureEnabled("Feature")) {
<script>
// If this feature is enabled
</script>
}
<script>
// Other JavaScript code
</script>
Run Code Online (Sandbox Code Playgroud)
这种方式的优点是它不会混淆JavaScript和Razor太多,因为混合它们会最终导致可读性问题.大文本块也不是很易读.