繁体   English   中英

用Java编写的Razor

[英]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
});

备注/提示:

  • 将任何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文件,并且您不是使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM