使用 JavaScript/Knockout 下拉列表中选定的值填充 MVC3 视图模型?

发布于 2024-12-21 08:42:46 字数 3620 浏览 1 评论 0原文

我正在寻找有关如何在检索列表并在下拉列表中选择项目后填充传递到视图的视图模型的建议。请注意,我还有一个用于 Ajax/Knockout 客户端代码的客户端视图模型,但这不是我要填充的视图模型。我可能必须从一个视图模型映射到另一个视图模型,但我不确定这是否是正确的解决方案。

查看 - 表单

在我的表单中,我使用 Knockout 和 JavaScript 作为下拉菜单。如何使用所选的县代码值填充视图模型 m.VMResidencyWTCS.ScCountyCd 字段?是否也可以捕获描述?如果是这样,这又将如何完成?

@model Apps.Model.ViewModels.AVMApplicationInfo
...
@using (Html.BeginForm("ApplicationDetails", "PersonalInfo"))
{
    <fieldset>
        <div class="appl-step">
      ...
            <div class="editor-label">
                <span class="error">*</span>@Html.LabelFor(m => m.VMResidencyWTCS.ScCountyCd) 
            </div>
            <div class="editor-field">
                <select id='counties' 
                        data-bind='
                            options: selectedResidencyState() ? counties : null, 
                            optionsValue : "CountyCd", 
                            optionsText: "CountyDescr", 
                            optionsCaption: "[Please select a county]", 
                            value: selectedCounty,
                            visible: (counties() && counties().length > 0 )'>
                </select>
                <span data-bind='
                    template: {name: "noInfoTemplate"},
                    visible: !(counties() && counties().length > 0)'>
                </span>
            </div>

查看 - JavaScript

这是我的脚本,用于回调县下拉列表的控制器。请注意,当在另一个下拉列表中选择一个州时,会填充县下拉列表。

<script type='text/javascript'>
    $(document).ready(function () {
    var residency = function () {
        this.selectedResidencyState = ko.observable();
        this.selectedCounty = ko.observable();
                    ...
        this.states = ko.observableArray();
        this.counties = ko.observableArray();
     ...

        this.selectedResidencyState.subscribe(function (stateCd) {
            this.selectedCounty(undefined);
            this.counties(undefined);

            if (stateCd != null) {
                $.ajax({
                    url: '@Url.Action( "GetCounties", "PersonalInfo")',
                    data: { stateCd: stateCd },
                    type: 'GET',
                    success: function (data) {
                        residencyViewModel.counties(data);
                    }
                });
            }
        } .bind(this));

    };

    var residencyViewModel = new residency();
    ko.applyBindings(residencyViewModel);

    //Load the states
    $.ajax({
        url: '@Url.Action( "GetResidencyStates", "PersonalInfo" )',
        type: 'GET',
        success: function (data) {
            residencyViewModel.states(data);
        }
    });
});
</script>

控制器

public class PersonalInfoController : Controller
{
…
    [HttpGet]
    public virtual ActionResult GetCounties(string stateCd)
    {
        var counties =
            (
                from county in this._countyRepository.All
                where (county.CountryCd == "USA" && county.ResidencyStateCd == stateCd)
                select new
                {
                    CountyCd = county.CountyCd,
                    CountyDescr = county.CountyDescr,
                    StateCd = county.ResidencyStateCd,
                    CountryCd = county.CountryCd // Added for populating model ?Needed?
                }
            ).ToList();

        return Json(counties, JsonRequestBehavior.AllowGet);
    }

I’m looking for advice on how to populate the viewmodel passed to the view after a list is retrieved and an item selected in a dropdown list. Note that I also have a client side viewmodel that is used for the Ajax/Knockout client code but this is not the view model that I am trying to populate. I may have to map from one view model to the other but I'm not sure if that is the correct solution.

View - Form

In my form I am using Knockout and JavaScript for my dropdowns. How can I populate the view model m.VMResidencyWTCS.ScCountyCd field with the county code value that is selected? Is it possible to also capture the desription? If so, how would this be done as well?

@model Apps.Model.ViewModels.AVMApplicationInfo
...
@using (Html.BeginForm("ApplicationDetails", "PersonalInfo"))
{
    <fieldset>
        <div class="appl-step">
      ...
            <div class="editor-label">
                <span class="error">*</span>@Html.LabelFor(m => m.VMResidencyWTCS.ScCountyCd) 
            </div>
            <div class="editor-field">
                <select id='counties' 
                        data-bind='
                            options: selectedResidencyState() ? counties : null, 
                            optionsValue : "CountyCd", 
                            optionsText: "CountyDescr", 
                            optionsCaption: "[Please select a county]", 
                            value: selectedCounty,
                            visible: (counties() && counties().length > 0 )'>
                </select>
                <span data-bind='
                    template: {name: "noInfoTemplate"},
                    visible: !(counties() && counties().length > 0)'>
                </span>
            </div>

View - JavaScript

This is my script for calling back to the controller for the county dropdown list. Note that the county dropdown is populated when a state is selected in another dropdown.

<script type='text/javascript'>
    $(document).ready(function () {
    var residency = function () {
        this.selectedResidencyState = ko.observable();
        this.selectedCounty = ko.observable();
                    ...
        this.states = ko.observableArray();
        this.counties = ko.observableArray();
     ...

        this.selectedResidencyState.subscribe(function (stateCd) {
            this.selectedCounty(undefined);
            this.counties(undefined);

            if (stateCd != null) {
                $.ajax({
                    url: '@Url.Action( "GetCounties", "PersonalInfo")',
                    data: { stateCd: stateCd },
                    type: 'GET',
                    success: function (data) {
                        residencyViewModel.counties(data);
                    }
                });
            }
        } .bind(this));

    };

    var residencyViewModel = new residency();
    ko.applyBindings(residencyViewModel);

    //Load the states
    $.ajax({
        url: '@Url.Action( "GetResidencyStates", "PersonalInfo" )',
        type: 'GET',
        success: function (data) {
            residencyViewModel.states(data);
        }
    });
});
</script>

Controller

public class PersonalInfoController : Controller
{
…
    [HttpGet]
    public virtual ActionResult GetCounties(string stateCd)
    {
        var counties =
            (
                from county in this._countyRepository.All
                where (county.CountryCd == "USA" && county.ResidencyStateCd == stateCd)
                select new
                {
                    CountyCd = county.CountyCd,
                    CountyDescr = county.CountyDescr,
                    StateCd = county.ResidencyStateCd,
                    CountryCd = county.CountryCd // Added for populating model ?Needed?
                }
            ).ToList();

        return Json(counties, JsonRequestBehavior.AllowGet);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无需解释 2024-12-28 08:42:46

请注意,我还有一个客户端视图模型,用于
Ajax/Knockout 客户端代码,但这不是我的视图模型
试图填充。我可能必须从一个视图模型映射到另一个视图模型
但我不确定这是否是正确的解决方案。

好的,有一些黄旗升起。

让我重申一下你的问题来验证我的理解:你有一个视图模型,它的可观察对象绑定到

您有第二个视图模型,并且想要将 vm1.mySelection 存储在 vm2.mySelection 中。

这是正确的吗?

如果是这样,我的第一个想法是:“你可能做错了。”请解释为什么您认为您需要这个,我们会告诉您是否有更好的方法。

其次,如果您确实需要此功能,您可以手动订阅 vm2 中的 vm1.mySelection,然后在 vm2 中设置相应的值。但同样,这感觉很黑客,而且你可能做错了。

Note that I also have a client side viewmodel that is used for the
Ajax/Knockout client code but this is not the view model that I am
trying to populate. I may have to map from one view model to the other
but I'm not sure if that is the correct solution.

Ok, there are some yellow flags going up.

Let me restate your question to verify my understanding: you've got a view model with an observable bound to a <select> box. Let's pretend it's vm1.mySelection.

You have a 2nd view model, and you want to store vm1.mySelection inside vm2.mySelection.

Is that correct?

If so, my first thought is, "You're probably doing it wrong." Please explain why you think you need this, and we'll tell you whether there's a better way.

Secondly, if you truly do need this, you could manually subscribe to vm1.mySelection inside vm2, then set the value accordingly in vm2. But again, this feels hackish, and you might be doing it wrong.

一紙繁鸢 2024-12-28 08:42:46

我的设计可能不是最好的。我有一个视图模型从服务器传递到视图语句中定义的视图 (@model Apps.Model.ViewModels.AVMApplicationInfo)。我在视图“表单”中广泛使用它来捕获信息以构建 Web 服务调用。

我需要添加一些级联下拉菜单来获取过滤后的信息。为此,我添加了剔除代码和客户端视图模型(var residencyViewModel = new residency(); ko.applyBindings(residencyViewModel); )。这用于通过 ajax 回调控制器以获取下拉值。选择下拉值后,我想将选择存储在 Apps.Model.ViewModels.AVMApplicationInfo 视图模型中。我不确定是否需要客户端视图模型,但我不确定如何编写此代码。

所选值还将用于后续级联下拉列表(作为另一个过滤器值)。某些下拉列表使用之前在表单中选择的多个下拉列表中选择的值;即,它们有多个过滤器,例如:国家、州、县、市。这是由于表结构无法更改造成的。最终,当完成所有选择后,必须使用所有选择填充 Apps.Model.ViewModels.AVMApplicationInfo 视图模型,以将值传递回服务器以进行 Web 服务调用。

这有道理吗?

My design may be not be the best. I have a view model being passed to the view from the server as defined in the view statement (@model Apps.Model.ViewModels.AVMApplicationInfo). I use this extensively in the view "form" to capture information to build a web service call.

I needed to add some cascading dropdowns to get filtered information. To do this I added the knockout code and the clientside view model (var residencyViewModel = new residency(); ko.applyBindings(residencyViewModel); ). This is used to call back to the controller via ajax to get the dropdown values. Once the dropdown value has been selected I would like to store the selection in the Apps.Model.ViewModels.AVMApplicationInfo view model. I'm not sure if I need the clientside view model but I'm not sure how else to code this.

The selected value would also be used for subsequent cascading dropdowns (as another filter value). Some dropdowns use the selected values from multiple dropdowns selected earlier in the form; i.e., they have more than one filter such as: country, state, county, municipality. This is due to the table structure which can't be changed. Ultimately though when all the selections have been made the Apps.Model.ViewModels.AVMApplicationInfo view model must be populated with all the selections to pass the values back to the server for the web service call.

Does that make sense?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文