在jQuery中更新HiddenFor,然后向控制器提交新值

时间:2012-12-26 19:48:03

标签: jquery asp.net-mvc jquery-ui razor asp.net-mvc-4

我已经花了好几个小时了,这让人很沮丧:

我的一个ViewModel属性是Allocations列表。对于每个分配,我显示一个jQueryUI滑块。在滑动时,DisplayFor元素将使用新值(包含滑块的新值)进行更新。

以下是代码:

JS:

var slider = someDiv.find(".sliderInitial");
slider.each(function () {
    $(this).slider(
        {
            min: 0,
            max: 10,
            value: $(this).parent().find(".pointsForSliderInitial").text(),
            orientation: "vertical",
            slide: function (event, ui)
            {
                var thisDiv = $(this).parent().find('.pointsForSliderInitial');
                thisDiv.text(ui.value);
                thisDiv.find('#pointsForSliderInitial').val(ui.value); //this line does nothing
                calculatePointsSumInitial();
            }
        }
   );

partialview(使用ViewModel):

@for (int i = 0; i < Model.Allocations.Count(); i++) 
{
<td>
    <div class="hidCategoryDescriptionInitial">
            @Html.(alloc => alloc.Allocations[i].CategoryName)
            - @Html.DisplayFor(alloc => alloc.Allocations[i].CategoryDescription)
    </div>
    <div class="pointsForSliderInitial round label">
        @Html.HiddenFor(alloc => alloc.Allocations[i].AllocationID, new { id = "pointsForSliderInitial" + i }) //this hidden isn't working as expected
        @Html.DisplayFor(alloc => alloc.Allocations[i].Points)
    </div>
    <div class="sliderInitial" />
</td>
}

这是一个局部视图,包含在Html.BeginForm()中。表单通过输入类型提交提交。

这很有效。但现在我还需要将新滑动的值提交给数据库。这是困难 - 如何将我的pointsForsliderInitial中的Html.DisplayFor()包含的值提交到数据库?

我需要提交一个提交,其中我的Allocation属性填充了从HiddenFor()获取的值,这些值应该包含我使用滑块更新的值。

每次提交时,模型Allocations属性都为null。

我在这里做错了什么?如果信息不完整,请告诉我。

编辑:

Allocations属性的Viewmodel定义是一个AllocationsViewModel类型的列表(这是一个viewmodel,它将来自DB中多个表的数据放在一起:

public List<AllocationsViewModel>  Allocations { get; set; }

为div输出html“pointsForSliderInitial”:

<div class="pointsForSliderInitial round label">
    <input data-val="true" data-val-number="The field AllocationID must be a number." 
    data-val-required="The AllocationID field is required." 
    id="pointsForSliderInitial0" 
    name="Allocations[0].AllocationID" 
    type="hidden" value="75" />
    0
</div>

编辑2

我在有用的评论和回答后取得了一些进展。首先,我更新了滑块创建和幻灯片事件:

 $(this).slider(
        {
            animate:true,
            min: 0,
            max: 10,
            value: $(this).parent().find("input.valueHolder").val(),
            orientation: "vertical",
            slide: function (event, ui)
            {
                var thisDiv = $(this).parent().find('.pointsForSliderInitial');
                var newValue = ui.value;
                thisDiv.text(newValue);
                thisDiv.find('.valueHolder').val(newValue);
            }

第二,我通过将属性[HiddenInput]添加到AllocationID和Points属性来更新AllocationsViewModel:

public class AllocationsViewModel
{
    [HiddenInput]
    public int AllocationID { get; set; }

    [HiddenInput]
    public int Points { get; set; }

    public DateTime LastUpdated { get; set; }
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
    public string CategoryDescription { get; set; }
}

最后,我更新了视图:

<div class="pointsForSliderInitial round label">
@Html.HiddenFor(alloc => alloc.Allocations[i].AllocationID)
@Html.HiddenFor(alloc => alloc.Allocations[i].Points,new {@class="valueHolder"})
</div>

完成所有这些操作后,当使用按钮提交表单时,控制器会正确地将对象传递给操作(按照应该填充“分配”列表)。但是,只有在我不使用滑块时才会发生这种情况。如果我使用滑块(更新隐藏的输入),则再次执行操作,将分配接收为null。所以只要我不干涉滑块就行。

不知何故,这个jQuery行破坏了一些东西:

thisDiv.find('.valueHolder').val(newValue);

我想我必须深入挖掘,因为在Firebug中,当我调试时,在执行此行之后,当我检查其val()时,它会给我“未定义”。

编辑3:

我发现了chrome调试的问题!这真的很有趣:我在滑动时切换了滑块事件的顺序:

slide: function (event, ui)
{
var thisDiv = $(this).parent().find('.pointsForSliderInitial');
var newValue = ui.value;
thisDiv.find('.valueHolder').val(newValue);
thisDiv.text(newValue);
}

在调用val(newValue)时正确设置了值。 但接下来的一行,设置.text(newValue)正在破坏隐藏和混淆我的模型,使其返回null为动作。我刚删除了thisDiv.text(newValue); - &GT;一切正常,我的模型会从滑块中获得更新的正确点。

1 个答案:

答案 0 :(得分:4)

@NunoCarmo是对的,.val(ui.value)也不适用于输入元素的div,使用.text()代替......

但无论如何,你应该将该滑块值存储在输入而不是div中,因为div内容不会在表单提交上发布。

我不确定使用

@Html.DisplayFor(alloc => alloc.Allocations[i].Points)

因为输出是普通的0

您必须使用输入,例如AllocationID使用隐藏的类似

的输入
@Html.HiddenFor(alloc => alloc.Allocations[i].Points,new {@class="valueHolder"})

然后在你的JS中你可以做到:

thisDiv.find('input.valueHolder').val(ui.value);

您还需要更改滑块设置:

value: $(this).parent().find("input.valueHolder").val(),