有没有办法在DropDownList更改事件上使用AJAX来动态修改页面上的局部视图?

时间:2013-03-04 20:09:25

标签: ajax asp.net-mvc partial-views onchange

有没有办法在DropDownList更改事件上使用AJAX来动态修改页面上的局部视图?

我的主页面有一个DropDownList(DropDownListFor)部分视图,它只包含一个“项目”列表。此部分视图中显示的项目取决于DropDownList中选择的项目。 DropDownList项与局部视图中的项之间存在1对多的关系。因此,当用户更改DropDownList的值时,部分视图中的内容将动态更改以反映DropDownList中选择的项目。

这是我的DropDownList:

<div data-role="fieldcontain">
    Choose Capsule:<br />
    @Html.DropDownListFor(x => x.CapsuleFK, new SelectList(Model.Capsules, "pk", "name", "pk"), new { id = "ddlCapsules" })
    <br />
</div>

这是我在同一页面上的部分视图声明:

<div data-role="fieldcontain">
    @Html.Partial("_FillerPartial", Model.Fillers)
</div>

我对Ajax不是很熟悉,但是看看其他例子,这就是我对Ajax的看法:

$(document).ready(function () {
    $('#ddlCapsules').change(function () {
        // make ajax call to modify the filler list partial view

        var selection = $('#ddlCapsules').val();
        var dataToSend = { cappk: selection };

        $.ajax({
            url: 'Process/GetFillersByCapsule',
            data: { cappk: dataToSend },
            success: function (data) {
                alert("server returned: " + data);
            }
        });
    });
});

最后,这是一个截图,显示正在发生的事情。通过更改“选择胶囊”下拉列表,我希望填充列表动态更新:

enter image description here

2 个答案:

答案 0 :(得分:2)

您可以使用ajax从控制器加载下拉列表作为部分视图。

控制器代码:

    [HttpGet]
    public virtual ActionResult GetFillersByCapsule(string cappk)
    {
        var model = //Method to get capsules by pk, this returns a ViewModel that is used to render the filtered list. 
        return PartialView("PartialViewName", model);
    }

主视图html:

<div id="filteredList">
</div >

部分视图

@model IEnumerable<MyCapsuleModel>
foreach (var x in Model)
{
     //Render the appropriate filtered list html.
}

您可以使用ajax加载已过滤的列表:

$('#ddlCapsules').change(function () {
    // make ajax call to modify the filler list partial view

    var selection = $('#ddlCapsules').val();
    var dataToSend = { cappk: selection };

    $.ajax({
        url: 'Process/GetFillersByCapsule',
        data: { cappk: dataToSend },
        success: function (data) {

            $("#filteredList").empty();
            $("#filteredList").html(data);
        }
    });
});

希望这会有所帮助。

答案 1 :(得分:1)

您无法更新部分本身,因为如果没有页面重新加载,部分将永远不会再次呈现。一旦你收到HTML,ASP就完成了,那时你就是你自己了。

当然,您可以使用JavaScript切换特定div或其他任何内容。你的例子特别尖叫Knockout,所以我推荐使用它。

更改HTML以将数据绑定添加到包含div:

<div data-role="fieldcontain" data-bind="foreach: filler">
    <button data-bind="text: name"></button>
</div>

你的DropDownList:

@Html.DropDownListFor(x => x.CapsuleFK, new SelectList(Model.Capsules, "pk", "name", "pk"), new { id = "ddlCapsules", data_bind = "event: { change: updateFillers }" })

然后,一些JavaScript:

var FillersViewModel = function () {
    var self = this;

    self.fillers = ko.observableArray([]);

    self.updateFillers = function () {
        var selection = $('#ddlCapsules').val();
        var dataToSend = { cappk: selection };

        $.ajax({
            url: 'Process/GetFillersByCapsule',
            data: { cappk: dataToSend },
            success: function (data) {
                self.fillers(data.fillers) // where `fillers` is an array
            }
        });
    }
}

var viewModel = new FillersViewModel();
ko.applyBindings(viewModel);

这是一个非常简单的示例,您需要做更多的工作才能使它在您的场景中完成您需要做的所有事情,但一般的想法是每次更改下拉列表时,Knockout将调用您的updateFillers方法,该方法将执行AJAX并将新数据放入fillers可观察数组中。 Knockout会自动跟踪对此数组的更改(因此是“可观察”部分),因此会自动触发更新依赖于页面的任何部分。在这种情况下,这是包含按钮的div。 foreach绑定将为数组的每个成员重复HTML内部。我在这里只使用了一个简单的按钮元素来说明,但是你需要包含创建特定按钮所需的完整HTML,如界面。 text绑定会将name的内容放在开始和结束标记之间。有关您拥有的所有绑定选项,请参阅:http://knockoutjs.com/documentation/introduction.html

你可以做更多的事情。您可以在foreach中重复实施模板而不是对HTML进行硬编码。并且,您可以使用局部视图来控制此模板的HTML。重要的是Knockout为您生成所有这些重复HTML的痛苦,这就是我推荐使用它的原因。

希望这足以让你开始。