Knockout选择列表显示正确的项目数,但没有文本或值

时间:2012-11-20 09:22:58

标签: knockout.js knockout-mapping-plugin

我有一种奇怪的情况,将我的视图模型绑定到选择列表显示正确的行数,但显示的数据为空;正确的选项元素数,但每个都有一个空值和文本。模型下面是正确的;选择一个值工作正常,保存后,我的视图模型代码保存正确的值。它没什么可见的。使用函数绑定有效;例如,这显示正确:

<select data-bind="options: promotionLevels, 
                   optionsText: function(item) {
                       return item().description();
                   }, 
                   optionsValue: function(item) {
                       return item().id();
                   },
                   value: promotionLevel, 
                   optionsCaption: 'Choose...'"></select>

虽然这不是:

<select data-bind="options: promotionLevels, 
                   optionsText: 'description',  
                   optionsValue: 'id', 
                   value: promotionLevel, 
                   optionsCaption: 'Choose...'"></select>

我对淘汰赛来说比较新,并且很想知道问题所在。

由于

[编辑] 由服务器生成的数据是:

"promotionLevels":[{"id":"f28391a0-8995-45a4-a360-1dd1ae38861b","description":"Beta"},{"id":"6fb6ad46-fff4-4da8-98ef-4ff469406a6c","description":"Development"},{"id":"f16d044a-4ea6-4001-844e-c8dad6227c04","description":"Production"},{"id":"1da6ac1f-7d31-ba64-fbce-c8623af6464f","description":"QA"},{"id":"bc34a34a-0c89-4215-a001-1ea40433b8a9","description":"Test"}]

转储数据,一旦通过ko绑定,促销级别为:

"promotionLevels": [
    {
      "id": "f28391a0-8995-45a4-a360-1dd1ae38861b",
      "description": "Beta",
      "__ko_mapping__": {
        "ignore": [],
        "include": [
          "_destroy"
        ],
        "copy": [],
        "mappedProperties": {
          "id": true,
          "description": true
        }
      }
    },
    {
      "id": "6fb6ad46-fff4-4da8-98ef-4ff469406a6c",
      "description": "Development",
      ...

我试过这个,但是依赖性太大了。

[编辑2]

页面代码为:

    var mapping = {
        promotionLevel: {
            create: function(ctx) {
                return ko.observable(new Foo.ReferenceDataModel(ctx));
            }
        },
        ...
    };

    var viewModel = @Html.Knockout().ToViewModel(this.Model, @<text>mapping</text>);
    ko.applyBindings(viewModel, $("#endpointEditor")[0]);

视图模型代码:

Foo.ReferenceDataModel = $.inherit(
Foo.ViewModelBase,
{
    __constructor: function(options) {
        this.__base();

        if (options && options.data) {
            ko.mapping.fromJS(options.data, options.mapping || { }, this);
        } else {
            this.id = ko.observable($.generateId());
            this.description = ko.observable();
        }

        this.save = function(data, e) {
            var self = this;
            var form = $(e.target).parents("form");
            $.validator.unobtrusive.parse(form);
            if (!$(form).valid()) {
                return;
            }

            if (options.callback) {
                options.callback(self);
            }
        };
    }
});

这是我继承的应用程序,并且有一组复杂的模型等。基本视图模型只是添加了默认的错误处理。

1 个答案:

答案 0 :(得分:1)

您的问题是,当您执行此代码时,ko.observable中有promotionLevels个对象:

var mapping = {
        promotionLevel: {
            create: function(ctx) {
                return ko.observable(new Foo.ReferenceDataModel(ctx));
            }
        },
        ...
    };

options binding仅支持optionsText中的属性名称或功能。

在您的情况下,因为项目是数组中的可观察对象,只是普通的属性名称(例如“描述”)不起作用,因此您需要使用函数optionsText: function(item) { return item().description(); },

但是如果你不这样做,你需要在你的集合中有可观察对象的事实,然后将你的映射修改为:

var mapping = {
        promotionLevel: {
            create: function(ctx) {
                return new Foo.ReferenceDataModel(ctx);
            }
        },
        ...
    };

然后简单的属性名称绑定应该起作用:

<select data-bind="options: promotionLevels, 
               optionsText: 'description',  
               optionsValue: 'id', 
               value: promotionLevel, 
               optionsCaption: 'Choose...'"></select>