Razor in Javascript
Razor in Javascript
我不知道如何在Javascript中使用剃刀语法。我想用我的模型中的项目制作Html.ListBoxFor。我以前用过:
@Html.ListBoxFor(x => x.TagIdList, (MultiSelectList)ViewBag.Tags, new { @class = "chzn-select", data_placeholder = "Tags..." })
正如你所看到的,我还想使用chzn-select类,以获得更好的布局。
目前,我只是将上面的HTML代码作为纯文本,但我希望从我的模型中获得这些东西。
有什么想法吗?
ASP.NET MVC中有我的代码:
@model Generator.Models.ExamModel
@{
ViewBag.Title = "Generate";
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script src="@Url.Content("~/Multiple_chosen/chosen.jquery.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/ListOfTags.js")" type="text/javascript"></script>
<script >
$(".chzn-select").chosen();
</script>
}
<link href="@Url.Content("~/Multiple_chosen/chosen.css")" rel="stylesheet" type="text/css" />
<h1>@ViewBag.Title</h1>
<h2>@ViewBag.Message</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Generate</legend>
<div class="editor-label">Numbers</div>
<div class="editor-field" id="NumberOfModels">
@Html.EditorFor(model => model.NumberOfQuestions)
</div>
<div class="editor-label">Tags</div>
<div id="itemsmodel"></div>
<br>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
还有一个javascript文件:
var models = document.getElementById("NumberOfQuestions");
var modelsTable = document.getElementById("itemsmodel");
models.addEventListener("change", drawModels, false);
function drawModels() {
var modelsNum = parseInt(models.value);
var curModels = modelsTable.childElementCount;
if (modelsNum > curModels) {
var delta = modelsNum - curModels;
for (var i = 0; i < delta; i++) {
var input = document.createElement("div");
input.className = "editor-field";
input.innerHTML = "@Html.ListBoxFor(x => x.TagIdList, (MultiSelectList)ViewBag.Tags, new { @class = '"chzn-select'", data_placeholder = '"Tags...'" })";
modelsTable.appendChild(input);
}
} else {
while (modelsTable.childElementCount > modelsNum) {
modelsTable.removeChild(modelsTable.lastChild);
}
}
}
drawModels();
我的视图模型:ExamModel.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ExamGenerator.Models
{
public class ExaminationModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<int> TagIdList { get; set; }
public int NumberOfQuestions { get; set; }
public string Content { get; set; }
}
}
控制器中的My ActionResult Generate():
public ActionResult Generate()
{
ViewBag.Tags = new MultiSelectList(genKolEnt.TAGS, "Id", "Name", null);
return View();
}
虽然您可以使用Razor在Javascript中生成HTML,但如果Javascript处于MVC视图中,我发现注入JS会导致维护问题。理想情况下,您希望所有JS都在单独的文件中,以便进行绑定/缓存,并能够中断JS代码(这在视图中更难)。
要么只向页面上的JS注入简单的东西,要么注入元素。
您可以将模板Razor列表注入到一个伪脚本块中,以便稍后从中提取html。type="text/template"
表示浏览器将忽略它,例如:
<script id="ListTemplate" type="text/template">
@Html.ListBoxFor(x => x.TagIdList, (MultiSelectList)ViewBag.Tags, new { @class = "chzn-select", data_placeholder = "Tags..." })
</script>
视图页面现在看起来是这样的(去掉了不相关的部分):
@section styles{
<link href="@Url.Content("~/Multiple_chosen/chosen.css")" rel="stylesheet" type="text/css" />
}
<h1>@ViewBag.Title</h1>
<h2>@ViewBag.Message</h2>
<script id="ListTemplate" type="text/template">
@Html.ListBoxFor(x => x.TagIdList, (MultiSelectList)ViewBag.Tags, new { @class = "chzn-select", data_placeholder = "Tags..." })
</script>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Generate</legend>
<div class="editor-label">Numbers</div>
<div class="editor-field" id="NumberOfModels">
@Html.EditorFor(model => model.NumberOfQuestions)
</div>
<div class="editor-label">Tags</div>
<div id="itemsmodel"></div>
<br>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
脚本现在看起来是这样的(带有JS作为注释的jQuery版本):
// ListOfTags.js file
// This is a shortcut DOM ready handler for $(document).ready(function(){ YOUR CODE HERE })
$(function () {
// Attach an event handler for the "change" event
$('#NumberOfQuestions').change(function () {
var $numberOfQuestions = $(this); // Convert current DOM element (the counter) to a jQuery element
var $modelsTable = $('#itemsmodel'); // document.getElementById("itemsmodel");
var modelsNum = ~~$numberOfQuestions.val(); // parseInt(models.value);
var curModels = $modelsTable.children().length; // modelsTable.childElementCount
var delta = modelsNum - curModels;
// While too few, add more
while (delta > 0) {
var $input = $('<div>').addClass('editor-field'); // document.createElement("div"); .className = "editor-field";
var template = $('#ListTemplate').html(); // Fetch the template from a script block (id="ListTemplate")
$input.html(template); // input.innerHTML =
$modelsTable.append($input); // modelsTable.appendChild(input);
delta--;
}
// While too many, remove the last
while (delta++ < 0) {
$modelsTable.children().last().remove(); // modelsTable.removeChild(modelsTable.lastChild);
}
}).change(); // Trigger an initial change event so it runs immediately
});
注意事项/提示:
- 将任何JS放在页面中的视图底部,这样更容易找到。
@section Scripts
在哪里并不重要,因为母版页决定了它在最终页面上的注入位置 - 默认情况下,总是在Javascript常量中使用单引号(
'
),这样嵌套字符串就可以是"
,这比'
更经常需要。这是一个很好的习惯。事实上,如果你使用了它们,你的代码可能已经工作了,因为你在引号中添加了'
转义,这会扰乱Razor的处理
例如:
= '@Html.ListBoxFor(x => x.TagIdList, (MultiSelectList)ViewBag.Tags, new { @class = "chzn-select", data_placeholder = "Tags..." })';
- 如果将
@RenderSection("styles", required: false)
添加到母版页,则可以对CSS执行与对脚本执行相同的操作(确保所有CSS都加载在页眉中(以保持一致性)。只需将它们放在@section styles
块中即可
例如
<head>
...
@Styles.Render("~/Content/css")
@RenderSection("styles", required: false)
...
</head>
~~
是将值转换为整数的parseInt
的方便(快速)替代方案- 使用
$
作为jQuery对象变量的前缀。这样可以更容易地记住何时使用jQuery方法与DOM属性
测试控制器代码:
private MultiSelectList TagList()
{
var items = new List<KeyValuePair<int, string>>() {
new KeyValuePair<int, string>(1, "MVC"),
new KeyValuePair<int, string>(2, "jQuery"),
new KeyValuePair<int, string>(3, "JS"),
new KeyValuePair<int, string>(4, "C#"),
new KeyValuePair<int, string>(5, "PHP")
};
MultiSelectList list = new MultiSelectList(items, "key", "value", null);
return list;
}
// Get request starts with one list
public ActionResult Test()
{
ExamModel vm = new ExamModel()
{
NumberOfQuestions = 1,
TagIdList = new List<int>()
};
ViewBag.Tags = TagList();
return View(vm);
}
[HttpPost]
public ActionResult Test(ExamModel model)
{
ViewBag.Tags = TagList();
return View(model);
}
如果它是一个静态JavaScript文件,并且您没有使用剃刀视图引擎动态生成它它将不起作用,因为在这种情况下,服务器端没有执行任何处理。它与访问静态html页面/css文件/image等相同…
另一方面,如果这个JavaScript是某个Razor视图的一部分,也就是说,当你的控制器操作中有return View()
(或类似的东西)时,它会被Razor查看引擎渲染,那么这个代码应该可以工作。
问题是,java脚本文件不是由服务器处理的,因此您将无法在那些使用ASP.NET MVC的文件中插入任何内容。另一方面,Razor文件是在服务器上处理的,所以您可以将数据插入其中(通过视图包或模型)。
一种方法是:
.cshtml:
<script>
var someVariable = '@model.data';
</script>
然后在javascript文件中使用这个变量:
function someFunction(){
var myData = window.someVariable;
}
另一种方法是将所有javascript都放在.cs.html文件中,并将其呈现为部分视图。
@Html.Partial("Path/to/javascript/in/razor/view")
编辑:看到你的代码,这对你没有多大帮助。
如果你想动态添加/删除dom元素,你必须使用javascript:要么用"document.createElement()"生成它们,要么如果你想进行一些服务器端处理,就通过ajax加载它们。
@Html.ListBoxFor
是一个服务器端助手,它生成标签并根据参数填充标签。您也可以使用javascript来实现这一点。
- onclick javascript in PHP
- javascript in jquery popup
- Javascript in Visual studio Web Api
- JavaScript in WebView - Android Studio
- JavaScript in Netbeans
- openDatabaseSync in Javascript in QT-Quick
- Javascript in partial (Ruby on Rails)
- javascript in onkeypress value
- 如何从 javascript in html 访问 Java 中的方法
- javascript in onXXX handler escaping of & in parameter
- Bootstrap3 remote modal with javascript in remote?
- Javascript in foreach Magento
- Indy TIdHTTPServer OnCommandGet javascript in html not execu
- Html and javascript in visual studio 2013
- JavaScript in AJAX Response
- JavaScript in SQL
- popover javascript in foreach php
- Javascript in Asp.net,C#
- JavaScript in HTML head, innerhtml 不起作用
- Load HTML with javaScript in <a href...> link