【问题标题】:How to use (assign & manipulate) Razor variables in Javascript如何在 Javascript 中使用(分配和操作)Razor 变量
【发布时间】:2020-03-19 22:42:26
【问题描述】:

我正在尝试为我正在创建的动态表创建一个简单的计数器。本质上,每次我向表中添加一行时,我都希望计数器增加 1。如果我可以避免的话,我会尽量避免向模型添加一些任意属性,但我真的很想知道如何得到这个上班。

我的表格从 2 行开始,并且是模型绑定到列表的。这里的目的是允许之后的每个新行都被赋予一个新的索引,以便它可以与表单一起提交并在我去的时候创建列表(一个提交操作在视图的更下方,addRow() 函数被调用一个不提交表单的按钮)

基本上这就是我的看法

@model AddUsers
@{
    ViewData["Title"] = "Add Users";
    var Counter = 2;
}

@section Scripts{

<script>
    function addCount() {
        var count = @Counter;
        console.log('count: ' + count + 'counter: ' + '@Counter');
        count = count + 1;
        @Counter = count;
        console.log('count: ' + count + 'counter: ' + '@Counter');
    }
</script>

    <script>
        function addRow() {
            var counter = @Counter;
            var table = document.getElementById("AddUsersTable");
            var row = table.insertRow(-1);
            var cell1 = row.insertCell(0);
            cell1.innerHTML = '<input type="text" asp-for="Users[' + counter + '].FirstName"/><br /><span asp-validation-for="Users[' + counter + '].FirstName class="text-danger"></span>';
            var cell2 = row.insertCell(1);
            cell2.innerHTML = '<input type="text" />';
            var cell3 = row.insertCell(2);
            cell3.innerHTML = '<input type="text" />';
            var cell4 = row.insertCell(3);
            cell4.innerHTML = '<input type="text" />';
            addCount();
        }
    </script>
}

当我调试它并在浏览器中查看日志和元素时,我看到以下内容。

我显然遗漏了一些重要的东西,因为这些都没有按预期工作。

本应是一个简单的计数器,结果却比我预期的更令人头疼。我尝试了here的一些答案和cmets以及我自己的修补无济于事。

【问题讨论】:

    标签: javascript asp.net-core razor


    【解决方案1】:

    您似乎想将计数添加到name 的编号。

    如下改变:

    @model AddUsers
    <button onclick="addRow()">Add Row</button>
    <table id="AddUsersTable">
        <tr>
            <th>UserName</th>
            <th>1</th>
            <th>2</th>
            <th>3</th>
        </tr>
        <tr>
            <td>Candy</td>
            <td>aaa1</td>
            <td>bbb1</td>
            <td>ccc1</td>
        </tr>
    </table>
    @section Scripts{
        <script>
            var counter = 2;//it must define outside the function
            function addRow() {            
                var table = document.getElementById("AddUsersTable");
                var row = table.insertRow(-1);
                var cell1 = row.insertCell(0);
                cell1.innerHTML = '<input type="text" asp-for="Users[' + counter + '].FirstName"/><br /><span asp-validation-for="Users[' + counter + '].FirstName class="text-danger"></span>';
                var cell2 = row.insertCell(1);
                cell2.innerHTML = '<input type="text" />';
                var cell3 = row.insertCell(2);
                cell3.innerHTML = '<input type="text" />';
                var cell4 = row.insertCell(3);
                cell4.innerHTML = '<input type="text" />';
                counter++;
            }
        </script>
    }
    

    结果:

    更新:

    1.型号:

    public class AddUsers
    {
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        [Required]
        public int Age { get; set; }
    }
    

    2.Index.cshtml:

    我建议你可以添加_ValidationScriptsPartial,它默认存在于你的模板中,它包含jquery-validatejquery-validation-unobtrusive。这样你就可以在客户端验证而不是在服务器端验证ModelState。

    @model IEnumerable<AddUsers>
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <button onclick="ShowPartial()">Add Row</button>
    
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Age)
                </th>
    
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Age)
                    </td>
                </tr>
            }
        </tbody>
    </table>
    <div id="CreateUserPartial" hidden>
        @await Html.PartialAsync("PartialView", new AddUsers())
    </div>
    @section Scripts
    {
        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
        <script>
            function ShowPartial() {
                $('#CreateUserPartial').removeAttr('hidden');
            }
        </script>
    }
    

    3.局部视图(位于Views/Shared/PartialView.cshtml):

    @model AddUsers
    
    <form asp-action="Create">
        <div class="form-group">
            <label asp-for="Name" class="control-label"></label>
            <input asp-for="Name" class="form-control" />
            <span asp-validation-for="Name" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Age" class="control-label"></label>
            <input asp-for="Age" class="form-control" />
            <span asp-validation-for="Age" class="text-danger"></span>
        </div>
        <div class="form-group">
            <input type="submit" value="Create" class="btn btn-primary" />
        </div>
    </form>
    

    4.控制器:

    public class AddUsersController : Controller
    {
        private readonly YourContext _context;
    
        public AddUsersController(YourContext context)
        {
            _context = context;
        }      
        // GET: AddUsers
        public async Task<IActionResult> Index()
        {
            return View(await _context.Users.ToListAsync());
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("Id,Name,Age")] AddUsers addUsers)
        {
            if (ModelState.IsValid)
            {
                _context.Add(addUsers);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(addUsers);
        }
    }
    

    结果:

    【讨论】:

    • 这看起来很棒!我希望将其存储在脚本之外的原因是,当用户提交具有无效值的表单时(比如他们省略了名字或姓氏等必填字段),视图会重置并且验证消息只会显示在上方表和新创建的行都消失了。关于如何在创建行后保留行并在返回视图后在表中显示验证消息的任何想法?
    • 另外,经过尝试,似乎提交表单后,用户列表只包含前两行,没有添加任何动态的。我会调查这两个问题,但如果您有任何想法,那就太好了。
    • 在编码之前,我想检查您的要求,您是否想要一个按钮AddRow,然后添加一个原始的空输入。然后您可以将数据填充到空输入。如果模型状态无效,视图可以显示错误信息,如果模型状态有效,数据将添加到视图中。
    • 如果是这样,您是否考虑使用引导模式或部分视图?js事件在服务器端操作后无法保留添加的行。所以,我建议您可以使用模式或部分视图单独显示表格。并且不需要做一个计数器来指定名称。
    • 是的,基本上这是工作流程。用户单击“添加行”以输入其他用户。页面上有一个提交按钮,一旦输入了所有用户,就会检查模型的有效性,如果缺少任何名字或姓氏字段,模型验证会阻止他们提交表单,并通过验证重定向回表单消息存在,但所有行中输入的所有动态行和值仍然存在,并将正确绑定到模型中的列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多