[英]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();
我的ViewModel: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; }
}
}
我在控制器中的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
});
备注/提示:
@section Scripts
位置无关紧要,因为母版页决定了将其注入最终页的位置。 '
),以便嵌套字符串可以是"
,这比'
经常需要。这是一种很好的习惯。实际上,如果您使用过它们,您的代码就可以像您已经在引号中添加了\\
转义,这会使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文件,并且您不是使用razor视图引擎动态生成的,则此文件将不起作用,因为在这种情况下,服务器端不会执行任何处理。 它与访问静态html页面/ css文件/图像等相同。
另一方面,如果此JavaScript是某些Razor视图的一部分,则意味着它由razor视图引擎呈现,当您在控制器操作中return View()
(或类似的东西)时,此代码应该可以工作。
问题是,服务器无法处理Java脚本文件,因此您将无法在使用ASP.NET MVC的文件中插入任何内容。 另一方面,Razor文件在服务器上处理,因此您可以将数据插入其中(通过查看包或模型)。
一种方法是:
.cshtml:
<script>
var someVariable = '@model.data';
</script>
然后在您的javascript文件中使用此变量:
function someFunction(){
var myData = window.someVariable;
}
另一种方法是将所有javascript保存在.cshtml文件中,并将其呈现为部分视图。
@Html.Partial("Path/to/javascript/in/razor/view")
编辑:看到您的代码,这对您没有太大帮助。
如果要动态添加/删除dom元素,则必须使用javascript:使用“ document.createElement()”生成它们,或者如果需要一些服务器端处理,则通过ajax加载它们。
@Html.ListBoxFor
是一个服务器端帮助程序,它根据参数生成并填充标签。 您也可以使用javascript。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.