Knockout.js从来自ajax请求的'options'中选择'value'作为js对象

时间:2013-05-14 13:44:02

标签: ajax knockout.js

关顶: 标题非常令人困惑,但我找不到正确的词语来描述我的情况,对不起。如果你能找到更好的东西,请建议你的。 我想我犯了一个简单的错误,因为我是淘汰赛的新手,但我整天都找不到它。

这就是我所拥有的:

<select data-bind="
    value: SelectedPm,
    options: PmList, 
    optionsText: 'Name'"></select>
<b>Selected PM:</b> <span data-bind="text: SelectedPm().Name"></span>

JavaScript的:

function PmModel(data) {
    this.Name = data.Name;
    this.Company = data.Company;
    this.Division = data.Division;
    this.EmpNo = data.EmpNo;

}

function ViewModel() {
    // Data
    var self = this;

    self.PmList = ko.observableArray([]);
    self.SelectedPm = ko.observable();

    // Operations
    ko.computed(function () {
        $.getJSON("/CumulativeReport/GetPmList", function (allData) {
            var mappedTasks = $.map(allData, function (item) { return new PmModel(item); });
            self.PmList(mappedTasks);
        });
    });
}

ko.applyBindings(new ViewModel());

在这种情况下,我在控制台中遇到下一个错误: 未捕获错误:无法解析绑定。 消息:TypeError:无法读取未定义的属性“名称”; 绑定值:text:SelectedPm()。Name

但是当我不使用getJSON并使用一些模拟数组

时,它可以正常工作
    function PmModel(data) {
        this.Name = data.Name;
        this.Company = data.Company;
        this.Division = data.Division;
        this.EmpNo = data.EmpNo;

    }

    function ViewModel() {
    // Data
    var self = this;

    self.PmList = ko.observableArray([]);
    self.SelectedPm = ko.observable();

    // Operations
    ko.computed(function () {
        self.PmList([{Name:'aaaa'}, {Name:'bbbb'}]);    
    });
}

ko.applyBindings(new ViewModel());

或者我将使用js字符串对象作为optionsValue

<select data-bind="
    value: SelectedPm,
    options: PmList, 
    optionsText: 'Name',
    optionsValue: 'Id'"></select>
<b>Selected PM:</b> <span data-bind="text: SelectedPm"></span>

的JavaScript

function PmModel(data) {
    var self = this;
    this.Name = ko.observable(data.Name);
    this.Company = ko.observable(data.Company);
    this.Division = ko.observable(data.Division);
    this.EmpNo = ko.observable(data.EmpNo);
    this.Id = ko.computed(function () { return self.Company() + "-" + self.Division() + "-" + self.EmpNo(); });
}

function ViewModel() {
    // Data
    var self = this;

    self.PmList = ko.observableArray([]);
    self.SelectedPm = ko.observable();

    // Operations
    ko.computed(function () {
        $.getJSON("/CumulativeReport/GetPmList", function (allData) {
            var mappedTasks = $.map(allData, function (item) { return new PmModel(item); });
            self.PmList(mappedTasks);
        });
    });
}

ko.applyBindings(new ViewModel());

有人能指出我做错了什么吗? 提前谢谢。


UPD1

我找到了让它发挥作用的方法。看起来不是很好,但至少它是有效的

<select data-bind="
    value: SelectedPm,
    options: PmList, 
    optionsText: 'Name'"></select>
<!-- ko if: SelectedPm -->
<b>Selected PM:</b> <span data-bind="text: SelectedPm().Name"></span>
<!--/ko-->

我的猜测是,当ajax调用被触发时,knockout触发了PmListSelectedPm)的依赖关系,并试图在UI中重新呈现依赖关系值,但请求处理的时间太长而且新值不是及时发送到SelectedPm。它看起来并不合法,首先是因为版本optionsValue工作正常。但我没有任何其他想法如何解释它,所以这只是我的猜测,如果有人对它有更清晰的认识或者回答,请分享。

1 个答案:

答案 0 :(得分:2)

嗯,问题是当你将视图模型绑定到页面时,SelectedPm只是一个空的observable,因此调用SelectedPm().Name会爆炸,因为没有name属性。 我不知道这是否正确,但我只是用我想要的命名属性初始化变量:

self.SelectedPm = ko.observable({ Name: '' });

这样,首次绑定到页面时没有问题。