BackboneJS:模型已获取,但 toJSON() 和 get() 方法不起作用
BackboneJS : the model is fetched, but toJSON() and get() methods don't work
仍在学习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());
returns 一个空对象。
但是当我执行 console.log(categories);
时,attributes
属性 包含数据。如果我尝试获取这些属性中的任何一个,它也不起作用 (undefined
)。
由于 JavaScript 异步执行,您的 console.log(categories.toJSON());
在 categories.fetch();
完成执行之前 执行。
这可以通过很多不同的方式解决,但这里有两种常见的方式:
第一个是使用 Backbone.Model 的 fetch()
方法,它接受 success
和 error
回调:
categories.fetch({
success: function() {
console.log(categories.toJSON());
}
});
这是一个例子(见 fiddle),它做同样的事情(但是从 GitHub API 中提取数据作为例子,因为它们有一个 public API).
第二种方式有点复杂,但在 Backbone 应用程序中是一种更常见的模式。这种方式包括在 CategoriesView
中添加一个 initialize
函数,并为 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)。我一直认为这很奇怪,所以我想我应该把它放在这里:)
仍在学习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());
returns 一个空对象。
但是当我执行 console.log(categories);
时,attributes
属性 包含数据。如果我尝试获取这些属性中的任何一个,它也不起作用 (undefined
)。
由于 JavaScript 异步执行,您的 console.log(categories.toJSON());
在 categories.fetch();
完成执行之前 执行。
这可以通过很多不同的方式解决,但这里有两种常见的方式:
第一个是使用 Backbone.Model 的 fetch()
方法,它接受 success
和 error
回调:
categories.fetch({
success: function() {
console.log(categories.toJSON());
}
});
这是一个例子(见 fiddle),它做同样的事情(但是从 GitHub API 中提取数据作为例子,因为它们有一个 public API).
第二种方式有点复杂,但在 Backbone 应用程序中是一种更常见的模式。这种方式包括在 CategoriesView
中添加一个 initialize
函数,并为 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)。我一直认为这很奇怪,所以我想我应该把它放在这里:)