【问题标题】:How do I populate a list field in a model from javascript?如何从 javascript 填充模型中的列表字段?
【发布时间】:2017-09-08 13:15:16
【问题描述】:

我有一个 Kendo.MVC 项目。该视图有一个模型,其字段类型为 List。我想从 Javascript 函数中填充列表。我尝试了几种方法,但无法使其正常工作。有人可以解释我做错了什么吗?

这是我的模型:

public class Dashboard
{
    public List<Note> ListNotes { get; set; }
}

我在视图上使用 ListNotes,如下所示:

foreach (Note note in Model.ListNotes)
{
    @Html.Raw(note.NoteText)
}

如果我在视图启动时在控制器中填充 Model.ListNotes,则此方法有效...

public ActionResult DashBoard(string xsr, string vst)
    {
        var notes = rep.GetNotesByCompanyID(user.ResID, 7, 7);
        List<Koorsen.Models.Note> listNotes = new List<Koorsen.Models.Note>();

        Dashboard employee = new Dashboard
        {
            ResID = intUser,
            Type = intType,
            FirstName = user.FirstName,
            LastName = user.LastName,
            ListNotes = listNotes
        };

        return View(employee);
    }

...但我需要在用户操作后在 Javascript 中填充 ListNotes。

这是我的 javascript 进行 ajax 调用以填充 ListNotes:

function getReminders(e)
{
    var userID = '@ViewBag.CurrUser';
    $.ajax({
        url: "/api/WoApi/GetReminders/" + userID,
        dataType: "json",
        type: "GET",
        success: function (notes)
        {
            // Need to assign notes to Model.ListNotes here
        }
    });
}

这是它通过 ajax 调用调用的方法。我已经确认 ListNotes 确实有我想要的值;它不是空的。

public List<Koorsen.Models.Note> GetReminders(int id)
    {
        var notes = rep.GetNotesByCompanyID(id, 7, 7);
        List<Koorsen.Models.Note> listNotes = new List<Koorsen.Models.Note>();

        foreach (Koorsen.OpenAccess.Note note in notes)
        {
            Koorsen.Models.Note newNote = new Koorsen.Models.Note()
            {
                NoteID = note.NoteID,
                CompanyID = note.CompanyID,
                LocationID = note.LocationID,
                NoteText = note.NoteText,
                NoteType = note.NoteType,
                InternalNote = note.InternalNote,
                NoteDate = note.NoteDate,
                Active = note.Active,
                AddBy = note.AddBy,
                AddDate = note.AddDate,
                ModBy = note.ModBy,
                ModDate = note.ModDate
            };

            listNotes.Add(newNote);
        }

        return listNotes;
    }

如果 ListNotes 是一个字符串,我会添加一个隐藏字段并用 Javascript 填充它。但这不适用于 ListNotes。我没有收到错误,但屏幕上的文字没有改变。

@Html.HiddenFor(x => x.ListNotes)
...
...
$("#ListNotes").val(notes);

我也试过了

@Model.ListNotes = notes; // This threw an unterminated template literal error

document.getElementById('ListNotes').value = notes;

我什至尝试在分配值后刷新页面:

window.location.reload();

并刷新代码所在的面板栏

var panelBar = $("#IntroPanelBar").data("kendoPanelBar");
panelBar.reload();

有人能解释一下如何让它工作吗?

我不知道这是否会使问题变得模糊,但我需要使用 ajax 调用在 javascript 中填充模型的原因是因为 Model.ListNotes 正在用于 Kendo 面板栏控件并且我不想要Model.ListNotes 有一个值,直到用户展开面板栏。

这是面板栏的代码:

@{
    @(Html.Kendo().PanelBar().Name("IntroPanelBar")
        .Items(items =>
        {
        items
        .Add()
        .Text("View Important Notes and Messages")
        .Expanded(false)
        .Content(
            @<text>
                    @RenderReminders()
            </text>
                );
        }
        )
    .Events(e => e
    .Expand("getReminders")
    )
    )
}

这是渲染内容的助手:

@helper RenderReminders()
{
    if (Model.ListNotes.Count <= 0)
    {
         @Html.Raw("No Current Messages");
    }
    else
    {
         foreach (Note note in Model.ListNotes)
         {
               @Html.Raw(note.NoteText)
               <br />
         }
    }
}

如果我在控制器中填充 Model.ListNotes 并将 Model 传递给视图,面板栏和助手工作正常。用户展开面板栏后,我无法将其填充到 javascript 中。

【问题讨论】:

  • 这是不了解应用程序所涉及技术状态的开发人员的经典问题。 Javascript 只能通过 ajax 向控制器发送数据,因此您只能通过这种方式从 JS 中分配一个 C# 值。您必须仅通过视图中的 JS 访问 JS 值,并将其发布到控制器以便将来在任何其他视图/请求中使用,但在相同的上下文中您无法这样做。
  • 您是否尝试将值分配给输入元素 type="hidden" 然后将其显示给用户?
  • 将值赋给隐藏控件并显示?是的,这是我尝试过的事情之一。我真正需要做的就是从 javascript 更改面板栏的内容。我尝试了各种方法,但没有任何效果。

标签: javascript jquery asp.net-mvc kendo-ui kendo-asp.net-mvc


【解决方案1】:

也许这会为你做到这一点。我将提供一个小的工作示例,我相信您可以轻松扩展以满足您的需求。我建议手动编写 html,而不是使用诸如 @html.raw 之类的辅助方法,因为 @html.raw 只是最终生成 html 的工具。无论如何,您都可以手动编写 html 来完成辅助方法所做的事情,我认为在这种情况下对您来说会更容易。如果您正确编写 html,它应该正确绑定到模型(这意味着它在您的发布请求模型上不会为空)因此,如果您使用 javascript 正确修改该 html,它也将正确绑定到您的模型。

查看其中一些示例,以更好地了解我在说什么:

http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/

所以回答你的问题... 您可以构建一个隐藏容器来保存您的列表值,如下所示(确保此容器位于表单内):

<div id="ListValues" style="display:none">
</div>

然后将您的 ajax 发布结果放入 javascript 变量(未显示)。 然后在javascript中做这样的事情:

        $('form').off('submit'); //i do this to prevent duplicate bindings depending on how this page may be rendered futuristically as a safety precaution.
        $('form').on('submit', function (e) { //on submit, modify the form data to include the information you want inside of your ListNotes
            
            var data = getAjaxResults(); //data represents your ajax results. You can acquire and format that how you'd like I will use the following as an example format for how you could save the results as JSON data: [{NoteID ="1",CompanyID ="2"}] 
            
            let listLength = data.length;
            for (let i = 0; i < listLength; i++) {
                $('#ListValues').append('<input type="text" name="ListNotes['+i+'].NoteID " value="' + data.NoteID +'" />') 
                $('#ListValues').append('<input type="text" name="ListNotes['+i+'].CompanyID " value="' + data.CompanyID +'" />') 
                 //for your ajax results, do this for each field on the note object
            }
            
        })

应该这样做!提交表单后,它应该会自动将模型绑定到您的 ListNotes!您将能够在调试器中对您的后控制器操作进行检查。

【讨论】:

    猜你喜欢
    • 2021-08-03
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多