将knockout viewmodel发送到控制器是从下拉框中丢失的项目

时间:2014-05-12 20:56:21

标签: c# asp.net-mvc-4 knockout-mvc

渐渐地,我正在学习这个......

在我的C#/ MVC4演示版本中,我创建了一个控制器,通过JSON将数据发送到我的视图。在我看来,我能够解析响应并填充下拉列表。

我正在使用类似于购物车的淘汰赛来创建额外的线条(颜色)以便发布到控制器。

代码:

MVC ViewModel:

function Color(data) {
    this.ID = ko.observable(data.ID);
    this.ColorName = ko.observable(data.ColorName);
    this.Duration = ko.observable(data.Duration);
    this.bNotPermanent = ko.observable(1);
}

function ViewModel() {
    self = this;
    self.CurrentColors = ko.observableArray([]);
    self.AddColors = ko.observableArray([]);
    self.AllColors = ko.observableArray([]);

    $.ajax({
        type: "POST",
        url: '@Url.Action("GetUsersColors", "EditUser")',
        data: { szUserRecID: RecID },
        success: function (data) {
            var colors = $.map(data, function (item) {
                return new Color(item)
            });
            self.CurrentColors(colors);
        },
        error: function (err) {
            alert(err.status + " : " + err.statusText);
        }
    })

    $.ajax({
        type: "POST",
        url: '@Url.Action("GetVisibleColors", "EditColor")',
        contentType: "application/json; charset=utf-8",
        dataType: "json", 
        data: {},
        success: function (data) {
            var colors = $.map(data, function (item) {
                return new Color(item)
            });
            self.AllColors(colors);
        },
        error: function (err) {
            alert(err.status + " - " + err.statusText);
        }
    })

    self.removeLine = function (color) { self.AddColors.remove(color);

    };
    self.addColor = function (color) { 
        self.AddColors.push(new Color({ ColorName: "", ID: "", Duration: "Permanent" }))
    };

    self.save = function () 
    {
        // I've also tried data: ko.mapping.toJSON(this) 
        // based on my issues I've seen, I'm almost positive this is where my issue is
        // I think the mapping is having an issue but I don't know what it should look like
        // with an array of objects
        $.ajax({
            url: '@Url.Action("PostColors", "EditColor")',
            type: "POST",
            data: ko.mapping.toJSON(this.AddColors()),
            async: true,
            contentType: "application/json"
        }).success(function (data) {

        });

};

这确实有用......

查看

<table>
<thead>
    <tr data-bind =" visible: $root.AddColors().length > 0">
        <th padding: 10px; >Color</th>
        <!--<th padding: 10px; >Duration</th>-->
    </tr>
</thead>
<tbody data-bind="foreach: AddColors">
    <tr>
    <!-- This works, it displays all the colors provided by the controller -->
        <td><select data-bind="options: $root.AllColors, optionsText: 'ColorName', value: ID, optionsCaption: 'Select Color...'"></select></td>
        <td>
            <a href='#' data-bind='click: $parent.removeLine'>Remove</a>
        </td>
    </tr>
</tbody>
</table>

<button data-bind='click: addColor'>Add Color</button>


<button data-bind='click: save'>Submit Colors</button>

控制器:

    [HttpPost]
    public void PostColors(List<ViewModels.ColorList> AddColors)
    {

           int t = 0; // to set a break point only
    }

C#ViewModel

    public class ColorList
{
    public int? ID { get; set; }
    public string ColorName { get; set; }
    public string Duration{ get; set; }
    public bool bNotPermanent { get; set; }
}

当我在上面的函数中检查AddColors时,设置了Duration,但ColorName为null,但我确实有正确数量的元素。

我可以在表单上反复添加行(颜色)并在列表中选择它们。但为什么它们没有显示在“AddColors”对象列表中呢?

我确实在这里找到了另一篇文章,指的是get;组;在viewmodel中,我确实添加了它。直到那一刻,所有事情都是空的。

Fiddler正在展示这个(它看起来不太正确......?)

[{"ID":    {"ID":11,"ColorName":"Green","Duration":null,"bNotPermanent":1},"ColorName":"","Duration":"Permanent","bNotPermanent":1},{"ID":    {"ID":17,"ColorName":"Red","Duration":null,"bNotPermanent":1},"ColorName":"","Duration":"Permanent","bNotPermanent":1}]

我真的认为我的问题在于数据转换/ ajax帖子。问题是,它应该是什么样的?

1 个答案:

答案 0 :(得分:1)

我猜你想要在添加的颜色条目的ID字段中显示颜色的ID。如果是这样,您需要做的是您需要设置optionsValue绑定以从所选项中选择单个属性,并使用该属性的值来设置要绑定的属性。

Knockout documentation on the options binding说明optionsValue绑定的以下内容。

  

与optionsText类似,您还可以传递一个名为optionsValue的附加参数,以指定应该使用哪些对象的属性来设置KO生成的元素的value属性。

由于您不希望将整个对象设置为添加颜色的ID属性,因此您希望Knockout从颜色中选择ID属性。所以只需更新你的绑定:

<select data-bind="options: $root.AllColors, 
                   optionsText: 'ColorName', 
                   value: ID, 
                   optionsCaption: 'Select Color...'">
</select>

为:

<select data-bind="options: $root.AllColors, 
                   optionsText: 'ColorName', 
                   optionsValue: ID,
                   value: ID, 
                   optionsCaption: 'Select Color...'">
</select>