在ASP.NET WebForms服务器端帖子之间坚持淘汰ViewModel ...

Gar*_*rom 5 javascript asp.net webforms knockout.js

使用这篇文章发布在CodeProject.com上," 在ASP.NET应用程序中使用KnockoutJS "作为指南我试图使用ASP.NET 3.5 Web窗体创建一个可重用的,数据加载的下拉列表,但是它利用KnockoutJS作为客户端数据绑定.此下拉列表的多个独立实例应该能够在同一页面中独立存在.

到目前为止,CodeProject.com帖子在指导我如何进行设置方面非常有价值,并且我成功地将更新后的ViewModel数据作为JSON字符串在服务器和客户端之间来回传递,并将其转换为对象(以及从对象转换)在服务器和客户端上).我所依赖的是应该是简单的部分; 将ViewModel绑定到下拉列表!

所以我首先将JSON字符串加载到隐藏字段中.它包括一个区域列表和一个SelectedRegion.

<input type="hidden" id="ddlRegionKO_hdnRegionListVMStorage" value="{&quot;Regions&quot;:[{&quot;RegionName&quot;:&quot;Mid Atlantic USA&quot;,&quot;RegionId&quot;:2},{&quot;RegionName&quot;:&quot;Mid West USA&quot;,&quot;RegionId&quot;:10},{&quot;RegionName&quot;:&quot;North Central USA&quot;,&quot;RegionId&quot;:5},{&quot;RegionName&quot;:&quot;North East USA&quot;,&quot;RegionId&quot;:1},{&quot;RegionName&quot;:&quot;North West USA&quot;,&quot;RegionId&quot;:7},{&quot;RegionName&quot;:&quot;Other&quot;,&quot;RegionId&quot;:9},{&quot;RegionName&quot;:&quot;South Central USA&quot;,&quot;RegionId&quot;:6},{&quot;RegionName&quot;:&quot;South East USA&quot;,&quot;RegionId&quot;:3},{&quot;RegionName&quot;:&quot;South West USA&quot;,&quot;RegionId&quot;:8}],&quot;SelectedRegion&quot;:{&quot;RegionName&quot;:&quot;North Central USA&quot;,&quot;RegionId&quot;:5}}" />
Run Code Online (Sandbox Code Playgroud)

然后我使用该ko.utils.parseJson()函数将此字符串转换为Javascript对象.

var stringViewModel = document.getElementById("ddlRegionKO_hdnRegionListVMStorage").value;
var ddlRegionKO_pnlRegionDDLContainer_ViewModel = ko.utils.parseJson(stringViewModel);
Run Code Online (Sandbox Code Playgroud)

然后,我转换属性定义成ko.observableko.observableArray方法(这是将要进行重构的部分之一,但作为一个概念证明就足够了).

//
// Convert all the model properties to KO Propety/Methods
for (var propertyName in ddlRegionKO_pnlRegionDDLContainer_ViewModel) {
    switch(propertyName.toUpperCase())
    {
        //
        // Multiple Region objects are stored as an array in the regions property.
        case "REGIONS":
            ddlRegionKO_pnlRegionDDLContainer_ViewModel[propertyName] = ko.observableArray(ddlRegionKO_pnlRegionDDLContainer_ViewModel[propertyName]);
            break;
        //
        // Only a single region may be selected at any time.
        case "SELECTEDREGION":
            ddlRegionKO_pnlRegionDDLContainer_ViewModel[propertyName] = ko.observable(ddlRegionKO_pnlRegionDDLContainer_ViewModel[propertyName]);
        break;
    };
};
Run Code Online (Sandbox Code Playgroud)

鉴于此,我希望在applyBindings调用方法时填充下拉列表并选择SelectedRegion ...

ko.applyBindings(ddlRegionKO_pnlRegionDDLContainer_ViewModel);
Run Code Online (Sandbox Code Playgroud)

我把这些全部放在了JSFiddle ...... 这里 ......我怀疑我可能会忽略一些东西,但我看不出它可能是什么.一切看起来都对我好.

如果有人能看到我忽略的东西,我将非常感激!

谢谢,

-G

haw*_*kke 2

您不需要在绑定中指定模型名称。而不是options:ddlRegionKO_pnlRegionDDLContainer_ViewModel.Regions,只需使用options:Regions等。

<select id="ddlRegionKO_ddlRegionList" 
    data-bind="options:Regions, 
        optionsText:'RegionName', 
        optionsValue:'RegionId',
        value:SelectedRegion, 
        optionsCaption:'Choose Region ...'">
</select>
Run Code Online (Sandbox Code Playgroud)

工作小提琴

编辑:您还缺少一个 optionsValue 绑定,该绑定指定您想要将哪个属性绑定到每个选项的值。我更新了小提琴以包含此更改。

编辑 2:嗯,您在 json 中选择的区域是一个对象。我查看了有关绑定的淘汰赛文档,但没有找到将选定值绑定到对象的方法,因此如果您可以修改 json,则只需指定选定值的 id 即可。

<input type="hidden" 
    id=".."
    data-bind="..a bunch of array stuff...  ,&quot;SelectedRegion&quot;:5}" 
/>
Run Code Online (Sandbox Code Playgroud)

看看我在那里做了什么?我替换了对象

'SelectedRegion':{'RegionName':'North Central USA','RegionId':5}
Run Code Online (Sandbox Code Playgroud)

只是:

'SelectedRegion':5
Run Code Online (Sandbox Code Playgroud)

更新的小提琴在这里。但这对您的文本框情况没有帮助,因为它会显示 ID 而不是文本框中的文本。现在有点晚了,所以我不太确定如何立即解决这个问题,但您可能会在这里寻找一些灵感。祝你好运。