淘汰赛:无法从observableArray获取特定值

时间:2014-10-19 11:43:40

标签: javascript knockout.js undefined client-side ko.observablearray

我创建了一个数组,其中包含有关viewmodel中某些音乐专辑的数据。我可以在foreach循环中使用这个数组(例如),但是我不能只显示这个数组中的一个值。

我的观点模型:

function CD(data) {
    this.Author = ko.observable(data.Author);
    this.Title = ko.observable(data.Title);
    this.Price = ko.observable(data.Price);
    this.Label = ko.observable(data.Label);
    this.Id = ko.observable(data.Id);
}

function NewsListViewModel() {
    var self = this;
    self.newsList = ko.observableArray([]);

    $.getJSON("/music/news", function (allData) {
        var mapped = $.map(allData, function (item) { return new CD(item) });
        self.newsList(mapped);
    });

    self.oneObject = ko.computed(function () {
        return self.newsList()[0].Title;
    });
}

$(document).ready(function () {
    ko.applyBindings(new NewsListViewModel());
});

我是如何在html中使用它的:

<ul data-bind="foreach: newsList">
     <li data-bind="text: Title"></li>
     <li data-bind="text: Author"></li>
     <li data-bind="text: Price"></li>
     <li data-bind="text: Label"></li>
</ul>

这完美无缺。但如果我尝试另外显示一个值:

<ul data-bind="foreach: newsList">
     <li data-bind="text: Title"></li>
     <li data-bind="text: Author"></li>
     <li data-bind="text: Price"></li>
     <li data-bind="text: Label"></li>
</ul>
...
<p data-bind="text: oneObject"</p>

它正在工作,firebug抛出错误:

  

类型错误:self.newsList()[0]。标题未定义

为什么我无法获得一个特定值,但我可以显示整个列表?

PS。代码<p data-bind="text: newsList()[0].Title"</p>也不起作用。

2 个答案:

答案 0 :(得分:3)

您收到错误,因为$.getJSON 异步

因此,当您的计算机被声明为newsList中没有必要准备好您的项目时,所以没有第一个元素可以访问。

所以你需要检查你的计算结果你的newsList不是空的(无论如何你的服务器也可以返回一个空列表,所以检查这个总是很好)然后只访问第一个元素:< / p>

self.oneObject = ko.computed(function () {
    if (self.newsList().length > 0)
        return self.newsList()[0].Title();
    return 'no title yet';
});

注意:您还需要编写.Title()来获取其值,因为Title是一个可观察的。

答案 1 :(得分:1)

我可以看到您的代码存在一些问题:

  1. $.getJSON是异步的,因此第一次被Knockout访问时self.newsList为空。这反过来意味着self.newsList[0]未定义。
  2. 计算出的observable中的
  3. return self.newsList()[0].Title;不会返回您希望它返回的值。它应该是return self.newsList()[0].Title();
  4. 您不必重新发明轮子,您可以使用映射插件来映射数据:http://knockoutjs.com/documentation/plugins-mapping.html