【问题标题】:KnockoutJS How to databind a set of drop down lists to an observable arrayKnockoutJS 如何将一组下拉列表数据绑定到可观察数组
【发布时间】:2012-04-24 00:07:25
【问题描述】:

My View 绑定到一个 Model 并显示几个下拉列表,它们的数量和选项基于模型中的某些属性。

我想使用knockout js将下拉列表中每个选定的值数据绑定到一个可观察的数组,跟踪哪个值属于哪个ddl。

使用以下代码显示每个下拉列表:

@for (var i = 0; i < Model.ProductProfiles.Count; i++)
        {
            var productProfile = Model.ProductProfiles[i];
            if (productProfile.IsVarying)
            {
                var lastItem = 0;           
                <div class="tab-pane" id="@productProfile.Name">                        
                    @for (var j = 0; j < productProfile.Attributes.Count; j++)
                    {           

                        <text>@productProfile.Attributes[j].Name</text>                                                     
                        @Html.DropDownListFor(m => m.ProductProfiles[i].SelectedValues[j], (SelectList)ViewData["Levels_" + i + "_" + j],
                        new { @class = "ddl-levels" })
                        <br />
                    }
                </div>
            }
        }

正确填写了下拉列表并正确设置了默认值(同时使用模型和 ViewData 中传递的选择列表)。

有没有办法将数据绑定到类似于以下内容的数组:

array[0]["0", "1", "3", "1",....] 其中 array[0] 指的是 Model.ProductProfiles[0] 并且数组的第二维是在 for 循环中显示的 ddl 的选定值 ?

我尝试将我的视图模型设置为简单

var viewModel = {
    selectedValues: ko.observableArray([])              
};

出于绝望,我尝试修改数据绑定值以模拟可观察数组中的位置访问:

@Html.DropDownListFor(m => m.ProductProfiles[i].SelectedValues[j], (SelectList)ViewData["Levels_" + i + "_" + j],
                        new { @class = "ddl-levels", data_bind = "value: productProfiles([" + i + "][" + j + "])" })

不幸的是它没有工作......

我希望已经清楚,否则我很乐意在被要求澄清时澄清。 有没有人可以帮助我?

谢谢

编辑:根据评论建议,我将多维数组拆分为 3 个可观察数组 像下面这样:

var viewModel = {        
    selectedValuesProd0: ko.observableArray(),
    selectedValuesProd1: ko.observableArray(),
    selectedValuesProd2: ko.observableArray()
}

然后我修改了HTML代码

var observableArrayProduct = "selectedValuesProd0";
                    if (i == 1)
                    {
                        observableArrayProduct = "selectedValuesProd1";
                    }
                    else if (i == 2)
                    {
                        observableArrayProduct = "selectedValuesProd2";
                    }

@Html.DropDownListFor(m => m.ProductProfiles[i].SelectedValues[j], (SelectList)ViewData["Levels_" + i + "_" + j], new { @class = "ddl-levels", data_bind = "value: " + observableArrayProduct + "()[" + j+ "]" })

如您所见,我仍在尝试对一维可观察数组进行位置访问,但当用户更改 DropDown 列表中的某些内容时,它仍然无法跟踪所选值。

此时我开始认为位置访问不起作用,但如果是这样,我还能做什么?

编辑 2:已解决!

好吧,我错过了一个关键步骤:可观察数组中的每个项目本身就是一个可观察值,所以我将其修复如下:

var viewModel = {        
    selectedValuesProd0: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[0], function(item) {
        return ko.observable(item);
    })),
    selectedValuesProd1: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[1], function(item) {
        return ko.observable(item);
    })),
    selectedValuesProd2: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[2], function(item) {
        return ko.observable(item);
    }))
}

其中 selectedValuesPerProduct 是使用从服务器端代码传递到视图的模型构建的二维数组(序列化后)。

希望对你有帮助!

【问题讨论】:

  • 我认为您的最后一条语句将评估为 data-bind="value: productProfiles([0][1])",(这不是数组的 eval,eval 是 data-bind="value :产品配置文件()[0][1]”)。无论如何,即使您将更改括号的顺序,这也无法正常工作(剔除数组不能是多维的)。当然,您可以创建可观察数组的可观察数组,但由于可维护性,我建议不要这样做。考虑创建普通视图模型而不是使用多维数组。
  • 感谢 Artem 的评论。因此,您建议为每组下拉列表创建一个单维 observableArray:这不是一个非常易于维护的解决方案,但是,如果没有其他事情要做,我会尝试,谢谢!

标签: asp.net-mvc-3 drop-down-menu knockout.js


【解决方案1】:

我建议像这样传递下拉菜单: {firstArray: [1,2,3], secondArray: [4,5,6]}

基本上,您不会按照您建议的方式保存任何工作。你可以让'firstArray'和'secondArray'不像你的索引器那样对人类友好。虽然我不确定为什么这会是一个有价值的目标;)我尽可能地追求可维护的代码。任何在你之后进来并看到多级索引器的人都不会欣赏你的聪明或后来他们的头痛。

【讨论】:

  • 操作我忘记了这个问题。最初我的可观察数组是一个二维数组,因为我想独立于我必须显示的产品数量和每个产品的属性数量。由于二维可观察数组在淘汰赛中不起作用,我不得不放弃与产品数量的独立性,从而拆分为 n 个可观察数组,每个数组的长度与每个产品的属性数相同。所以没有真正的多级方法,每个可观察数组都是单维的,并且每个下拉菜单都包含选定的值。
【解决方案2】:

我意识到我从未关闭过这个问题,所以我在这里添加一个回复:

好吧,我错过了一个关键步骤:可观察数组中的每个项目本身就是一个可观察值,所以我将其修复如下:

var viewModel = {        
selectedValuesProd0: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[0], function(item) {
    return ko.observable(item);
})),
selectedValuesProd1: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[1], function(item) {
    return ko.observable(item);
})),
selectedValuesProd2: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[2], function(item) {
    return ko.observable(item);
}))

}

其中 selectedValuesPerProduct 是使用从服务器端代码传递到视图的模型构建的二维数组(序列化后)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    • 2019-05-21
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 2017-07-26
    相关资源
    最近更新 更多