还在学习Backbone,这是我的代码
const API_URL = 'http://api.brewerydb.com/v2';
const API_KEY = '********************************';
var Categories = Backbone.Model.extend({
url: API_URL + '/categories/?key=' + API_KEY
});
var CategoriesView = Backbone.View.extend({
tagName: 'ul',
id: 'categories',
render: function()
{
var html = '';
for (var i = 0; i < this.model.get('data').length; i++)
{
html += '<li>' + this.model.get('data')[i].name + '</li>';
}
this.$el.html(html);
}
});
var categories = new Categories();
categories.fetch();
console.log(categories.toJSON());
我的console.log(categories.toJSON());
会返回一个空对象。
但是当我执行console.log(categories);
时,attributes
属性包含数据。如果我尝试使用任何这些属性,它也不起作用(undefined
)。
答案 0 :(得分:1)
由于JavaScript以异步方式执行,因此console.log(categories.toJSON());
在 categories.fetch();
执行完毕之前执行。
这可以通过很多不同的方式解决,但这里有两个常见的方法:
第一种方法是使用Backbone.Model的fetch()
方法,它接受success
和error
个回调:
categories.fetch({
success: function() {
console.log(categories.toJSON());
}
});
以下是一个示例(请参阅fiddle),它执行相同的操作(但是从GitHub API中提取数据作为示例,因为它们具有公共API)。
第二种方式有点复杂,但在Backbone应用程序中是一种更常见的模式。这种方式包括在initialize
中添加CategoriesView
函数,并为Backbone的同步事件添加事件监听器。该事件将触发回调,之后您可以执行渲染功能。
它还要求您在调用新视图构造函数时传入对模型的引用(请参阅下面代码中的最后一行以了解如何完成此操作。)
这可能看起来有点令人困惑,所以我又制作了另一个fiddle,显示了这一点,再次从GitHub API中提取数据。
除了GitHub API示例之外,您的代码现在看起来像这样:
const API_URL = 'http://api.brewerydb.com/v2';
const API_KEY = '********************************';
var Categories = Backbone.Model.extend({
url: API_URL + '/categories/?key=' + API_KEY
});
var CategoriesView = Backbone.View.extend({
tagName: 'ul',
id: 'categories',
initialize: function()
{
this.model.fetch();
this.listenTo(this.model, 'sync', this.render);
},
render: function()
{
// Your data will show up
// in this case
console.log(categories.toJSON());
var html = '';
for (var i = 0; i < this.model.get('data').length; i++)
{
html += '<li>' + this.model.get('data')[i].name + '</li>';
}
this.$el.html(html);
}
});
var categories = new Categories();
// Create a new instance of the view,
// and pass in the model you just
// created
var categoriesView = new CategoriesView({ model: categories });
您可能会注意到一个奇怪的事情是,在您看来,listenTo
sync
事件,不 fetch
事件。这是因为从Backbone 1.0开始,model.fetch()
实际上会触发sync
事件(source)。我一直认为这很奇怪,所以我想我会把它丢在这里:)