在ASP之间持久化knockout ViewModel.. NET WebForms服务器端帖子

Persisting knockout ViewModel between ASP.NET WebForms server side posts ...

本文关键字:WebForms 服务器端 NET ViewModel ASP 之间 持久化 knockout      更新时间:2023-09-26

使用CodeProject.com上的这篇文章,"在你的ASP中使用KnockoutJS。作为指导,我尝试使用ASP创建一个可重用的、数据加载的下拉列表。NET 3.5 Web Forms,但它利用KnockoutJS进行客户端数据绑定。此下拉列表的多个独立实例应该能够独立地存在于同一页面中。

到目前为止,CodeProject.com的帖子在指导我如何设置东西方面是非常宝贵的,我成功地将更新的ViewModel数据作为JSON字符串在服务器和客户端之间来回传递,并将其转换为对象(在服务器和客户端上)。我挂在嘴边的应该是最简单的部分;将ViewModel绑定到下拉列表!

所以我首先将JSON字符串加载到一个隐藏字段中。它包括一个region列表和一个selecteregion。

<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}}" />

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

var stringViewModel = document.getElementById("ddlRegionKO_hdnRegionListVMStorage").value;
var ddlRegionKO_pnlRegionDDLContainer_ViewModel = ko.utils.parseJson(stringViewModel);

然后我将属性定义转换为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;
    };
};

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

ko.applyBindings(ddlRegionKO_pnlRegionDDLContainer_ViewModel);

我把这些都放在JSFiddle…在这里……我怀疑我可能忽略了一些东西,但我看不出它可能是什么。在我看来一切都很好。

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

谢谢,

- g

您不需要在绑定中指定模型名称。不用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>
工作小提琴

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

编辑2:嗯,你在json中选择的区域是一个对象。我看了关于绑定的knockout文档,我没有看到将选定值绑定到对象的方法,所以如果可能的话,你可以修改json,你可以指定选定值的id。
<input type="hidden" 
    id=".."
    data-bind="..a bunch of array stuff...  ,&quot;SelectedRegion&quot;:5}" 
/>

看到我做的了吗?我替换了对象

'SelectedRegion':{'RegionName':'North Central USA','RegionId':5}
只有:

'SelectedRegion':5

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