[英]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.