簡體   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