单一型号不显示路由器
Single model doesn't show with router
我看不懂怎么展示单品。当我想显示产品页面(模型视图 - app.ProductItemView in productPageShow)时,我得到 "Uncaught TypeError: Cannot read property 'get' of undefined at child.productPageShow (some.js:58)" >> this.prod = this.prodList.get(id);
这是我的代码:
// Models
var app = app || {};
app.Product = Backbone.Model.extend({
defaults: {
coverImage: 'img/placeholder.png',
id: '1',
name: 'Unknown',
price: '100'
}
});
app.ProductList = Backbone.Collection.extend({
model: app.Product,
url: 'php/listProducts.php'
});
// Views
app.ProductListView = Backbone.View.extend({
el: '#product-list',
initialize: function() {
this.collection = new app.ProductList();
this.collection.fetch({ reset: true });
this.render();
this.listenTo(this.collection, 'reset', this.render);
},
render: function() {
this.collection.each(function(item) {
this.renderProduct(item);
}, this);
},
renderProduct: function(item) {
app.productView = new app.ProductView({
model: item
});
this.$el.append(app.productView.render().el);
}
});
app.ProductItemView = Backbone.View.extend({
tagName: 'div',
template: _.template($('#productPage').html()),
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
app.ProductView = Backbone.View.extend({
tagName: 'div',
template: _.template($('#productTemplate').html()),
render: function() {
this.$el.html(this.template(this.model.attributes));
return this;
}
});
// Router
app.Router = Backbone.Router.extend({
routes: {
"list": 'list',
"product/:id": "productPageShow"
},
initialize: function() {
this.$content = $("#product-list");
},
list: function() {
this.prodList = new app.ProductList();
this.productListView = new app.ProductListView({ model: this.prodList });
this.prodList.fetch();
this.$content.html(app.productListView.el);
},
productPageShow: function(id) {
this.prod = this.prodList.get(id);
this.prodItView = new app.ProductItemView({ model: this.prod });
this.$content.html(this.prodItView.el);
}
});
$(function() {
new app.Router();
Backbone.history.start();
});
代码存在一些概念性问题,没有深入细节,路由器中发生的很多事情不属于那里,但对于一个(当前)非复杂的应用程序来说是可管理的.
我将重点关注 app.Router 文件,因为这很可能是您遇到问题的罪魁祸首。
routes: {
"list": 'list',
"product/:id": "productPageShow"
}
让我们从基础开始,当您在 Backbone 路由器(或其他框架中的任何其他路由器)中定义路由列表时,您为路由提供了一个键,该键将对应于 [=76] 中的某些内容=] 路由器将识别并调用回调方法。
如果您将浏览器导航至:
http://your-url#list
Backbone 将调用 list
回调
类似地:
http://your-url#product/1
Backbone 将调用 productPageShow
回调
须知:只能调用一个路由回调! Backbone 路由器第一次找到匹配的路由时,它将调用该回调并跳过所有其他
在您的代码中,您依赖的事实是 this.prodList 将存在于 productPageShow
方法中,但这只会发生在您首先转到 list
路线然后到 product/{id}
路线。
另一件事 .. 在路由器的 list
回调中,您在 ProductListView 实例上设置了 model
.. 但是 model
既不是用户,也不是 model
因为 this.productList
是 Backbone.Collection
此外,您需要知道 fetch
是一个异步操作,并且您没有使用任何回调来保证在需要时获得数据(除了依赖 'reset' 事件)。
所以这将是我尝试使其可行的方法:
// Models
var app = app || {};
app.Product = Backbone.Model.extend({
defaults: {
coverImage: 'img/placeholder.png',
id: '1',
name: 'Unknown',
price: '100'
}
});
app.ProductList = Backbone.Collection.extend({
model: app.Product,
url: 'php/listProducts.php'
});
// Views
app.ProductListView = Backbone.View.extend({
el: '#product-list',
initialize: function() {
this.render();
this.listenTo(this.collection, 'reset', this.render);
},
render: function() {
this.collection.each(function(item) {
this.renderProduct(item);
}, this);
},
renderProduct: function(item) {
app.productView = new app.ProductView({
model: item
});
this.$el.append(app.productView.render().el);
}
});
app.ProductItemView = Backbone.View.extend({
tagName: 'div',
template: _.template($('#productPage').html()),
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
app.ProductView = Backbone.View.extend({
tagName: 'div',
template: _.template($('#productTemplate').html()),
render: function() {
this.$el.html(this.template(this.model.attributes));
return this;
}
});
// Router
app.Router = Backbone.Router.extend({
routes: {
"": "list",
"product/:id": "productPageShow"
},
initialize: function() {
this.$content = $("#product-list");
},
list: function() {
this.prodList = new app.ProductList();
this.productListView = new app.ProductListView({ collection: this.prodList });
this.prodList.fetch({reset:true});
this.$content.html(app.productListView.el);
},
productPageShow: function(id) {
try {
this.prod = this.prodList.get(id);
this.prodItView = new app.ProductItemView({ model: this.prod });
this.$content.html(this.prodItView.el);
} catch (e) {
// Navigate back to '' route that will show the list
app.Router.navigate("", {trigger:'true'})
}
}
});
$(function() {
app.Router = new app.Router();
Backbone.history.start();
});
所以在没有完整图片的情况下在黑暗中拍摄了一点,这就是变化:
ProductListView
不再实例化在 Router
的 list
回调中完成的 ProductList
集合
- 将路由从 'list' 更改为 '',这将保证列表立即显示
- 如果
productPageShow
中没有可用的产品数据,请导航回 list
我看不懂怎么展示单品。当我想显示产品页面(模型视图 - app.ProductItemView in productPageShow)时,我得到 "Uncaught TypeError: Cannot read property 'get' of undefined at child.productPageShow (some.js:58)" >> this.prod = this.prodList.get(id);
这是我的代码:
// Models
var app = app || {};
app.Product = Backbone.Model.extend({
defaults: {
coverImage: 'img/placeholder.png',
id: '1',
name: 'Unknown',
price: '100'
}
});
app.ProductList = Backbone.Collection.extend({
model: app.Product,
url: 'php/listProducts.php'
});
// Views
app.ProductListView = Backbone.View.extend({
el: '#product-list',
initialize: function() {
this.collection = new app.ProductList();
this.collection.fetch({ reset: true });
this.render();
this.listenTo(this.collection, 'reset', this.render);
},
render: function() {
this.collection.each(function(item) {
this.renderProduct(item);
}, this);
},
renderProduct: function(item) {
app.productView = new app.ProductView({
model: item
});
this.$el.append(app.productView.render().el);
}
});
app.ProductItemView = Backbone.View.extend({
tagName: 'div',
template: _.template($('#productPage').html()),
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
app.ProductView = Backbone.View.extend({
tagName: 'div',
template: _.template($('#productTemplate').html()),
render: function() {
this.$el.html(this.template(this.model.attributes));
return this;
}
});
// Router
app.Router = Backbone.Router.extend({
routes: {
"list": 'list',
"product/:id": "productPageShow"
},
initialize: function() {
this.$content = $("#product-list");
},
list: function() {
this.prodList = new app.ProductList();
this.productListView = new app.ProductListView({ model: this.prodList });
this.prodList.fetch();
this.$content.html(app.productListView.el);
},
productPageShow: function(id) {
this.prod = this.prodList.get(id);
this.prodItView = new app.ProductItemView({ model: this.prod });
this.$content.html(this.prodItView.el);
}
});
$(function() {
new app.Router();
Backbone.history.start();
});
代码存在一些概念性问题,没有深入细节,路由器中发生的很多事情不属于那里,但对于一个(当前)非复杂的应用程序来说是可管理的.
我将重点关注 app.Router 文件,因为这很可能是您遇到问题的罪魁祸首。
routes: {
"list": 'list',
"product/:id": "productPageShow"
}
让我们从基础开始,当您在 Backbone 路由器(或其他框架中的任何其他路由器)中定义路由列表时,您为路由提供了一个键,该键将对应于 [=76] 中的某些内容=] 路由器将识别并调用回调方法。
如果您将浏览器导航至:
http://your-url#list
Backbone 将调用 list
回调
类似地:
http://your-url#product/1
Backbone 将调用 productPageShow
回调
须知:只能调用一个路由回调! Backbone 路由器第一次找到匹配的路由时,它将调用该回调并跳过所有其他
在您的代码中,您依赖的事实是 this.prodList 将存在于 productPageShow
方法中,但这只会发生在您首先转到 list
路线然后到 product/{id}
路线。
另一件事 .. 在路由器的 list
回调中,您在 ProductListView 实例上设置了 model
.. 但是 model
既不是用户,也不是 model
因为 this.productList
是 Backbone.Collection
此外,您需要知道 fetch
是一个异步操作,并且您没有使用任何回调来保证在需要时获得数据(除了依赖 'reset' 事件)。
所以这将是我尝试使其可行的方法:
// Models
var app = app || {};
app.Product = Backbone.Model.extend({
defaults: {
coverImage: 'img/placeholder.png',
id: '1',
name: 'Unknown',
price: '100'
}
});
app.ProductList = Backbone.Collection.extend({
model: app.Product,
url: 'php/listProducts.php'
});
// Views
app.ProductListView = Backbone.View.extend({
el: '#product-list',
initialize: function() {
this.render();
this.listenTo(this.collection, 'reset', this.render);
},
render: function() {
this.collection.each(function(item) {
this.renderProduct(item);
}, this);
},
renderProduct: function(item) {
app.productView = new app.ProductView({
model: item
});
this.$el.append(app.productView.render().el);
}
});
app.ProductItemView = Backbone.View.extend({
tagName: 'div',
template: _.template($('#productPage').html()),
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
app.ProductView = Backbone.View.extend({
tagName: 'div',
template: _.template($('#productTemplate').html()),
render: function() {
this.$el.html(this.template(this.model.attributes));
return this;
}
});
// Router
app.Router = Backbone.Router.extend({
routes: {
"": "list",
"product/:id": "productPageShow"
},
initialize: function() {
this.$content = $("#product-list");
},
list: function() {
this.prodList = new app.ProductList();
this.productListView = new app.ProductListView({ collection: this.prodList });
this.prodList.fetch({reset:true});
this.$content.html(app.productListView.el);
},
productPageShow: function(id) {
try {
this.prod = this.prodList.get(id);
this.prodItView = new app.ProductItemView({ model: this.prod });
this.$content.html(this.prodItView.el);
} catch (e) {
// Navigate back to '' route that will show the list
app.Router.navigate("", {trigger:'true'})
}
}
});
$(function() {
app.Router = new app.Router();
Backbone.history.start();
});
所以在没有完整图片的情况下在黑暗中拍摄了一点,这就是变化:
ProductListView
不再实例化在Router
的 - 将路由从 'list' 更改为 '',这将保证列表立即显示
- 如果
productPageShow
中没有可用的产品数据,请导航回list
list
回调中完成的 ProductList
集合