我对Knockout很新,而且确实是Javascript,所以我毫不怀疑我的问题是愚蠢的。但我发现KnockoutJS的文档假设您已经了解了很多关于Javascript的内容,因此这些示例对我来说还不够完整。
我有一个返回JSON数据的REST API,如下所示:
{"$id":"1","$values":
[
{"$id":"2",
"id":14,
"name":"Bound to pretend",
"artist":
{"$id":"3",
"id":12,
"name":"Velvet Veins"
}},
{"$id":"4",
"id":13,
"name":"This Is It",
"artist":
{"$id":"5",
"id":11,
"name":"Michael Jackson"
}}
]
}
因此响应是ShortAlbumDto
个对象的数组,其中一个属性是Artist
类型的另一个对象。
我试图使用KnockoutJS在表格中显示这些数据。这是HTML:
<table class="table table-hover">
<thead>
<tr>
<th>Artist</th>
<th>Name</th>
</tr>
</thead>
<tbody data-bind="foreach: albums">
<tr>
<td data-bind="text: artist.name"></td>
<td data-bind="text: name"></td>
</tr>
</tbody>
</table>
我的KnockoutJS组件(在Home组件中使用)是这样的:
相册-latest.js:
define(['knockout', 'text!./albums-latest.html'], function(ko, templateMarkup) {
function AlbumsLatest(params) {
var self = this;
self.albums = ko.observableArray([]);
$.getJSON('http://localhost:62755/api/album/latest', self.albums)
}
// This runs when the component is torn down. Put here any logic necessary to clean up,
// for example cancelling setTimeouts or disposing Knockout subscriptions/computeds.
AlbumsLatest.prototype.dispose = function() { };
return { viewModel: AlbumsLatest, template: templateMarkup };
});
home.html的:
<h2>Home</h2>
<albums-latest></albums-latest>
albums-latest已在startup.js中正确注册:
define(['jquery', 'knockout', './router', 'bootstrap', 'knockout-projections'], function($, ko, router) {
// Components can be packaged as AMD modules, such as the following:
ko.components.register('nav-bar', { require: 'components/nav-bar/nav-bar' });
ko.components.register('home-page', { require: 'components/home-page/home' });
// ... or for template-only components, you can just point to a .html file directly:
ko.components.register('about-page', {
template: { require: 'text!components/about-page/about.html' }
});
ko.components.register('albums-latest', { require: 'components/albums-latest/albums-latest' });
// [Scaffolded component registrations will be inserted here. To retain this feature, don't remove this comment.]
// Start the application
ko.applyBindings({ route: router.currentRoute });
});
(我使用yeoman作为脚手架并添加组件)。
我的问题是,当我执行此操作时,Firebug会告诉我artist is not referenced
。 CORS已启用,我可以看到Ajax请求触发,WebApi返回数据只是找到 - 我似乎无法以Knockout理解的方式映射它。
答案 0 :(得分:1)
试试这个:
$.getJSON('http://localhost:62755/api/album/latest', function(r) {
self.albums(r.$values);
});
在您的情况下,响应直接映射到albums
数组(因为getJSON(url, observable)
与getJSON(url, function(r) { observable(r); })
基本相同),但是ajax请求返回一个对象其中$values
属性包含实际的专辑数组。