Javascript 淘汰赛:Can';无法从observableArray获取特定值

Javascript 淘汰赛:Can';无法从observableArray获取特定值,javascript,knockout.js,undefined,client-side,ko.observablearray,Javascript,Knockout.js,Undefined,Client Side,Ko.observablearray,我用viewmodel中一些音乐专辑的数据创建了一个数组。例如,我可以在foreach循环中使用这个数组,但我不能只显示这个数组中的一个值 我的viewmodel: function CD(data) { this.Author = ko.observable(data.Author); this.Title = ko.observable(data.Title); this.Price = ko.observable(data.Price); this.Labe

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

我的viewmodel:

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>
...
由于
$.getJSON
异步的,因此会出现错误

因此,当您的computed被声明时,您的项目在
新闻列表中没有必要准备就绪,因此没有您可以访问的第一个元素

因此,您需要在计算机中检查您的
新闻列表
是否为空(无论如何,您的服务器也可以返回一个空列表,因此进行此检查总是好的),然后才访问第一个元素:

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

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

您获取错误是因为
$。getJSON
异步的

因此,当您的computed被声明时,您的项目在
新闻列表中没有必要准备就绪,因此没有您可以访问的第一个元素

因此,您需要在计算机中检查您的
新闻列表
是否为空(无论如何,您的服务器也可以返回一个空列表,因此进行此检查总是好的),然后才访问第一个元素:

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

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

我发现您的代码存在一些问题:

  • $.getJSON
    是异步的,因此当首次被Knockout访问时,
    self.newsList
    是空的。这反过来意味着
    self.newsList[0]
    未定义
  • 返回self.newsList()[0]。标题不会返回您希望它返回的值。它应该是
    返回self.newsList()[0].Title()
  • 您不必重新发明轮子,您可以使用映射插件映射数据:

  • 我发现您的代码存在一些问题:

  • $.getJSON
    是异步的,因此当首次被Knockout访问时,
    self.newsList
    是空的。这反过来意味着
    self.newsList[0]
    未定义
  • 返回self.newsList()[0]。标题不会返回您希望它返回的值。它应该是
    返回self.newsList()[0].Title()
  • 您不必重新发明轮子,您可以使用映射插件映射数据:

  • 这不仅仅是异步问题。KO在定义计算函数时立即调用该函数,以便为其设置依赖关系链。@T.J.Crowder,因为OP无论如何都希望首先将数组元素设置为空,并检查
    self.newsList()。length
    创建依赖关系。立即执行computed函数没有问题,因为在声明computed之前,
    self.newsList
    已经声明并且存在。解决方案很好。我的问题是开头的句子,但再看一遍OP的代码,它确实适用。@nemesv:这是有道理的!感谢您的解释和解决方案。问题解决了。这不仅仅是异步问题。KO在定义计算函数时立即调用该函数,以便为其设置依赖关系链。@T.J.Crowder,因为OP无论如何都希望首先将数组元素设置为空,并检查
    self.newsList()。length
    创建依赖关系。立即执行computed函数没有问题,因为在声明computed之前,
    self.newsList
    已经声明并且存在。解决方案很好。我的问题是开头的句子,但再看一遍OP的代码,它确实适用。@nemesv:这是有道理的!感谢您的解释和解决方案。问题已解决。旁注:没有任何理由编写
    ko.observearray([])
    。只要
    ko.observearray()
    就足够了。旁注:没有任何理由编写
    ko.observearray([])
    。只要
    ko.observearray()
    就足够了。