我正在尝试使用Backbone.js并且很新,但是无法在以下代码中的View初始化函数中正确绑定this.listenTo。
这个骨干代码是一个单独的js文件。
'use strict';
let Preloadcart = function ( $, Backbone, _ ) {
// console.log(Backbone);
console.log(this);
let
// fnSelf = this,
// Model-each unit comprises of this
Service = Backbone.Model.extend({
defaults:{
title:'',
price: 0,
checked: false
},
type: 'Service',
toggleCheck: () => {
this.set('checked', !this.get('checked'));
}
}),
// Collection- of such Service instances
ServiceList = Backbone.Collection.extend({
// collection based on this model
model: Service,
type: 'ServiceList',
// get model instances with attribute checked=true
getChecked: () => {
console.log(`checking ${this.type}`);
return this.where({checked:true});
},
}),
services = new ServiceList([
new Service({ title: 'web development', price: 200}),
new Service({ title: 'web design', price: 250}),
new Service({ title: 'photography', price: 100}),
new Service({ title: 'coffee drinking', price: 10})
// Add more here
]),
// View of each Service model unit
ServiceView = Backbone.View.extend({
tagName: 'li',
type: 'ServiceView',
events: {
'click': 'toggleService'
},
initialize: () => {
console.log(`initializing ${this.type}`);
_.bindAll(this, 'toggleService', 'render');
this.listenTo(this.model, 'change', this.render);
},
toggleService: () => {
this.model.toggle();
},
render: () => {
let
$frag = $(document.createDocumentFragment()),
$htmlCheckbox = $('<input>', {
type:'checkbox',
value: 1,
name: this.model.get('title'),
}),
$htmlSpan = $('<span>', {
value: `\$${this.model.get('price')}`,
});
$htmlCheckbox.append(this.model.get('title'));
$htmlCheckbox.append($htmlSpan);
this.$htmlCheckbox.prop('checked', this.model.get('checked'));
$frag.append($htmlCheckbox);
this.$el.append($frag);
return this;
}
}),
App = Backbone.View.extend({
el: $('#main'),
type: 'App',
initialize: function () {
// listen on the collection instance of ServiceList, services
console.log(`initializing App ${this.type}`);
let
view, that= this;
this.total = 0,
this.collection = services;
_.bindAll(this, 'render');
this.listenTo(this.collection, 'change', this.render);
_(this.collection.models).each( (model) => {
view = new ServiceView();
view.set({model: model});
that.$('#services').append(view.render().el);
}, this);
},
render: () => {
_.each(this.collection.getChecked(), (each) => {
this.total += each.get('price');
});
this.$('#total-value').text(`\$${this.total}`);
}
}),
AppView = new App();
// new App();
// return App;
};
export default Preloadcart;
这在主js文件中调用如下:
$(() => {
Preloadcart($, Backbone, _, that);
});
但抛出错误:
preloadCart.js:57 Uncaught TypeError: Cannot read property 'type' of undefined
我在错误日志中跟踪的问题似乎在这里:
_.bindAll(this, 'toggleService', 'render');
和
console.log(`initializing ${this.type}`);
在ServiceView intialize
函数下;
this
未定义。我错过了什么?
如果对代码有任何疑惑,请告诉我,我会尽量使这更简单。
答案 0 :(得分:1)
initialize: () => {
console.log(`initializing ${this.type}`);
_.bindAll(this, 'toggleService', 'render');
this.listenTo(this.model, 'change', this.render);
},
定义初始化函数时调用箭头操作符。 就在调用Preloadcart的时候。所以在函数初始化中,&#39;这个&#39;不是观点对象,而是&#39;这个&#39;当Preloadcart被调用时。使用正常功能。
initialize: function() {
console.log(`initializing ${this.type}`);
_.bindAll(this, 'toggleService', 'render');
this.listenTo(this.model, 'change', this.render);
},