Uncaught Type Error: View is not a constructor
Uncaught Type Error: View is not a constructor
我有未捕获的类型错误:UserRegisterView 不是 constructor.I 不明白这个 error.I 查看了所有代码,但我没有找到它。
对不起我的坏事english.Please帮帮我
感谢回答
已更新
UserRegisterView 在这里
var UserRegisterView = Backbone.View.extend({
model: User,
el: '#form',
events: {
'click input[id="infoWeek"]': 'infoWeek',
'click input[id="infoMonth"]': 'infoMonth'
},
infoWeek: function() {
this.$el.find("#dayOfMonth").hide();
this.render();
},
infoMonth: function() {
this.$el.find("#dayOfWeek").hide();
this.render();
}
});
var AddUserView = Backbone.View.extend({
el: $(".page"),
events: {
'click #saveUser': 'saveUser'
},
saveUser: function() {
var user = new User();
user.set({
username: $("#username").val(),
lastName: $("#lastName").val(),
regNumber: $("#regNumber").val(),
password: $("#password").val(),
departmentName: $("#departmentName").val(),
email: $("#email").val(),
role: $("#role").val()
});
user.save();
if (document.getElementById('isOpen').checked) {
user.set("isOpen", $("#isOpen").val("1"));
user.save();
} else {
user.set("isOpen", $("#isOpen").val("0"));
user.save();
}
if (document.getElementById('dayOfWeek').checked) {
user.set("dayOfWeek", $("#dayOfWeek").val());
user.save();
} else if (document.getElementById('dayOfMonth').checked) {
user.set("dayOfMonth", $("#dayOfMonth").val());
user.save();
}
$("#username").val("");
$("#firstName").val("");
$("#lastName").val("");
$("#regNumber").val("");
$("#password").val("");
$("#deparmentName").val("");
$("#email").val("");
$("#isOpen").val("");
$("#dayOfWeek").val("");
$("#dayOfMonth").val("");
},
render: function() {
var that = this;
var template = Handlebars.compile(UserRegister);
var myHtml = template(that.model.toJSON());
that.$el.html(myHtml);
return this;
}
});
return {
AddUserView: AddUserView,
UserRegisterView: UserRegisterView
};
});
路由器用户功能
define([
'jquery',
'underscore',
'backbone',
'handlebars',
'spin',
'app/models/LoginModel',
'app/views/LoginView',
'app/views/UserRegisterView'
], function($,
_,
Backbone,
Handlebars,
Spinner,
Login,
LoginView,
UserRegisterView
) {
var Router = Backbone.Router.extend({
routes: {
'search': 'search',
'login': 'login',
'travels': 'travels',
'user': 'user',
'menu': 'menu',
'': 'home'
},
user: function() {
disposeView(new UserRegisterView().render());
}
dispose.view 在 util.js
function disposeView(view) {
Backbone.View.prototype.close = function() {
this.unbind();
this.undelegateEvents();
};
/* Şu anki viewi yok et */
if (this.currentView !== undefined) {
this.currentView.close();
}
/* Yeni view oluştur. */
this.currentView = view;
this.currentView.delegateEvents();
return this.currentView;
}
发生了什么事
您的 UserRegisterView
模块 return 是一个包含两个构造函数的对象。
return {
AddUserView: AddUserView,
UserRegisterView: UserRegisterView
};
使用该模块时,得到的就是上面的对象。
define([
// ...
'app/views/UserRegisterView'
], function(
// ...
UserRegisterView // value of the return in the module
) {
所以您将其称为 UserRegisterView
有点 误导自己,因为它不是构造函数,而是包含构造函数的对象。
要使用当前模块设置方式获取新的 UserRegisterView
视图实例,您需要这样调用它:
var userView = new UserRegisterView.UserRegisterView();
或者创建一个 AddUserView
实例:
var addView = new UserRegisterView.AddUserView();
解决方案
- 拆分模块,每个视图构造函数一个。
- 更改名称,这样至少不会产生误导(如
UserViewsModule
)
其他改进
话虽如此,您的 Backbone 代码还可以进行其他改进。
var UserRegisterView = Backbone.View.extend({
// that's useless (if not used) and not a view property.
// model: User,
// don't use `el` like that, especially when using the view as a shared Constructor
el: '#form',
events: {
'click input[id="infoWeek"]': 'onInfoWeekClick',
'click input[id="infoMonth"]': 'onInfoMonthClick'
},
initialize: function() {
// Cache jQuery object of the view's element
this.$dayOfMonth = this.$("#dayOfMonth");
this.$dayOfMonth = this.$("#dayOfMonth");
// also use the shortcut function instead of `this.$el.find()`
}
onInfoWeekClick: function(e) {
this.$dayOfMonth.hide();
// calling render here is useless unless your using it as a parent
// view, where the child view overrides the render function.
},
onInfoMonthClick: function(e) {
this.$dayOfMonth.hide();
}
});
disposeView
函数可以简化:
function disposeView(view) {
var current = this.currentView;
if (current) current.close();
current = this.currentView = view;
current.delegateEvents();
return current;
}
不要在每次调用函数时更改默认的 Backbone 视图原型。相反,只添加一次函数。
_.extend(Backbone.View.prototype, {
close: function() {
this.unbind();
this.undelegateEvents();
},
// any other function you want to add can go here.
});
在另一个答案中,我详细介绍了 。
您已经在使用 jQuery,所以不要使用 JavaScript DOM API document.getElementById('isOpen')
穿插 jQuery 选择器 $('#isOpen')
.
我对以下视图做了一些改进。花时间为自己创建一些实用函数(如 reset
和 getValues
)以简化代码流并封装复杂性。
var AddUserView = Backbone.View.extend({
el: $(".page"),
events: {
'click #saveUser': 'saveUser'
},
// compile the template once while creating the view class
template: Handlebars.compile(UserRegister),
// get the selector string out of the code and place them in one place
// easy to change and maintain.
fields: {
username: "#username",
firstName: "#firstName",
lastName: "#lastName",
regNumber: "#regNumber",
password: "#password",
deparmentName: "#deparmentName",
email: "#email",
isOpen: "#isOpen",
dayOfWeek: "#dayOfWeek",
dayOfMonth: "#dayOfMonth",
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
// cache jQuery object of every field once after a render
this.field = _.reduce(this.fields, function(fields, selector, key) {
fields['$' + key] = this.$(selector);
return fields;
}, {}, this);
return this;
},
reset: function() {
// reset all the fields once without repeating code.
_.each(this.field, function($field) {
$field.val("");
});
return this;
},
getValues: function(keys) {
// get the value of multiple fields returned in a nice object
// ready to be sent to a Backbone model.
return _.reduce(keys, function(data, key) {
data[key] = this.field[key].val();
return data;
}, {}, this);
},
saveUser: function() {
var field = this.field,
user = new User(this.getValues([
'username',
'lastName',
'regNumber',
'password',
'departmentName',
'email',
'role',
]));
user.set({ isOpen: field.$isOpen.is(':checked') });
if (field.$dayOfWeek.is(':checked')) {
user.set("dayOfWeek", field.$dayOfWeek.val());
} else if (field.$dayOfMonth.is(':checked')) {
user.set("dayOfMonth", field.$dayOfMonth.val());
}
user.save();
this.reset();
},
});
在以下代码段中,您将上下文 (this
) 放入局部变量中。我看到了很多,我可以说 90% 的时间我在 Stack Overflow 问题上看到它,这是没有意义的。分明就是复制粘贴。
render: function() {
var that = this;
// ...
that.$el.html(myHtml);
return this;
}
请告诉我你看到你将 this
放入 that
,然后在整个函数中使用 that
,然后你仍然 return this
?!
当动态创建的回调中需要对象时,将上下文放入局部变量很有用。
render: function() {
var that = this; // this is available here
setTimeout(function() {
// here this is not available.
that.handleCallback();
}, 10);
// here we are in the same context as the first line.
return this;
}
我有未捕获的类型错误:UserRegisterView 不是 constructor.I 不明白这个 error.I 查看了所有代码,但我没有找到它。 对不起我的坏事english.Please帮帮我
感谢回答
已更新
UserRegisterView 在这里
var UserRegisterView = Backbone.View.extend({
model: User,
el: '#form',
events: {
'click input[id="infoWeek"]': 'infoWeek',
'click input[id="infoMonth"]': 'infoMonth'
},
infoWeek: function() {
this.$el.find("#dayOfMonth").hide();
this.render();
},
infoMonth: function() {
this.$el.find("#dayOfWeek").hide();
this.render();
}
});
var AddUserView = Backbone.View.extend({
el: $(".page"),
events: {
'click #saveUser': 'saveUser'
},
saveUser: function() {
var user = new User();
user.set({
username: $("#username").val(),
lastName: $("#lastName").val(),
regNumber: $("#regNumber").val(),
password: $("#password").val(),
departmentName: $("#departmentName").val(),
email: $("#email").val(),
role: $("#role").val()
});
user.save();
if (document.getElementById('isOpen').checked) {
user.set("isOpen", $("#isOpen").val("1"));
user.save();
} else {
user.set("isOpen", $("#isOpen").val("0"));
user.save();
}
if (document.getElementById('dayOfWeek').checked) {
user.set("dayOfWeek", $("#dayOfWeek").val());
user.save();
} else if (document.getElementById('dayOfMonth').checked) {
user.set("dayOfMonth", $("#dayOfMonth").val());
user.save();
}
$("#username").val("");
$("#firstName").val("");
$("#lastName").val("");
$("#regNumber").val("");
$("#password").val("");
$("#deparmentName").val("");
$("#email").val("");
$("#isOpen").val("");
$("#dayOfWeek").val("");
$("#dayOfMonth").val("");
},
render: function() {
var that = this;
var template = Handlebars.compile(UserRegister);
var myHtml = template(that.model.toJSON());
that.$el.html(myHtml);
return this;
}
});
return {
AddUserView: AddUserView,
UserRegisterView: UserRegisterView
};
});
路由器用户功能
define([
'jquery',
'underscore',
'backbone',
'handlebars',
'spin',
'app/models/LoginModel',
'app/views/LoginView',
'app/views/UserRegisterView'
], function($,
_,
Backbone,
Handlebars,
Spinner,
Login,
LoginView,
UserRegisterView
) {
var Router = Backbone.Router.extend({
routes: {
'search': 'search',
'login': 'login',
'travels': 'travels',
'user': 'user',
'menu': 'menu',
'': 'home'
},
user: function() {
disposeView(new UserRegisterView().render());
}
dispose.view 在 util.js
function disposeView(view) {
Backbone.View.prototype.close = function() {
this.unbind();
this.undelegateEvents();
};
/* Şu anki viewi yok et */
if (this.currentView !== undefined) {
this.currentView.close();
}
/* Yeni view oluştur. */
this.currentView = view;
this.currentView.delegateEvents();
return this.currentView;
}
发生了什么事
您的 UserRegisterView
模块 return 是一个包含两个构造函数的对象。
return { AddUserView: AddUserView, UserRegisterView: UserRegisterView };
使用该模块时,得到的就是上面的对象。
define([
// ...
'app/views/UserRegisterView'
], function(
// ...
UserRegisterView // value of the return in the module
) {
所以您将其称为 UserRegisterView
有点 误导自己,因为它不是构造函数,而是包含构造函数的对象。
要使用当前模块设置方式获取新的 UserRegisterView
视图实例,您需要这样调用它:
var userView = new UserRegisterView.UserRegisterView();
或者创建一个 AddUserView
实例:
var addView = new UserRegisterView.AddUserView();
解决方案
- 拆分模块,每个视图构造函数一个。
- 更改名称,这样至少不会产生误导(如
UserViewsModule
)
其他改进
话虽如此,您的 Backbone 代码还可以进行其他改进。
var UserRegisterView = Backbone.View.extend({
// that's useless (if not used) and not a view property.
// model: User,
// don't use `el` like that, especially when using the view as a shared Constructor
el: '#form',
events: {
'click input[id="infoWeek"]': 'onInfoWeekClick',
'click input[id="infoMonth"]': 'onInfoMonthClick'
},
initialize: function() {
// Cache jQuery object of the view's element
this.$dayOfMonth = this.$("#dayOfMonth");
this.$dayOfMonth = this.$("#dayOfMonth");
// also use the shortcut function instead of `this.$el.find()`
}
onInfoWeekClick: function(e) {
this.$dayOfMonth.hide();
// calling render here is useless unless your using it as a parent
// view, where the child view overrides the render function.
},
onInfoMonthClick: function(e) {
this.$dayOfMonth.hide();
}
});
disposeView
函数可以简化:
function disposeView(view) {
var current = this.currentView;
if (current) current.close();
current = this.currentView = view;
current.delegateEvents();
return current;
}
不要在每次调用函数时更改默认的 Backbone 视图原型。相反,只添加一次函数。
_.extend(Backbone.View.prototype, {
close: function() {
this.unbind();
this.undelegateEvents();
},
// any other function you want to add can go here.
});
在另一个答案中,我详细介绍了
您已经在使用 jQuery,所以不要使用 JavaScript DOM API document.getElementById('isOpen')
穿插 jQuery 选择器 $('#isOpen')
.
我对以下视图做了一些改进。花时间为自己创建一些实用函数(如 reset
和 getValues
)以简化代码流并封装复杂性。
var AddUserView = Backbone.View.extend({
el: $(".page"),
events: {
'click #saveUser': 'saveUser'
},
// compile the template once while creating the view class
template: Handlebars.compile(UserRegister),
// get the selector string out of the code and place them in one place
// easy to change and maintain.
fields: {
username: "#username",
firstName: "#firstName",
lastName: "#lastName",
regNumber: "#regNumber",
password: "#password",
deparmentName: "#deparmentName",
email: "#email",
isOpen: "#isOpen",
dayOfWeek: "#dayOfWeek",
dayOfMonth: "#dayOfMonth",
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
// cache jQuery object of every field once after a render
this.field = _.reduce(this.fields, function(fields, selector, key) {
fields['$' + key] = this.$(selector);
return fields;
}, {}, this);
return this;
},
reset: function() {
// reset all the fields once without repeating code.
_.each(this.field, function($field) {
$field.val("");
});
return this;
},
getValues: function(keys) {
// get the value of multiple fields returned in a nice object
// ready to be sent to a Backbone model.
return _.reduce(keys, function(data, key) {
data[key] = this.field[key].val();
return data;
}, {}, this);
},
saveUser: function() {
var field = this.field,
user = new User(this.getValues([
'username',
'lastName',
'regNumber',
'password',
'departmentName',
'email',
'role',
]));
user.set({ isOpen: field.$isOpen.is(':checked') });
if (field.$dayOfWeek.is(':checked')) {
user.set("dayOfWeek", field.$dayOfWeek.val());
} else if (field.$dayOfMonth.is(':checked')) {
user.set("dayOfMonth", field.$dayOfMonth.val());
}
user.save();
this.reset();
},
});
在以下代码段中,您将上下文 (this
) 放入局部变量中。我看到了很多,我可以说 90% 的时间我在 Stack Overflow 问题上看到它,这是没有意义的。分明就是复制粘贴。
render: function() { var that = this; // ... that.$el.html(myHtml); return this; }
请告诉我你看到你将 this
放入 that
,然后在整个函数中使用 that
,然后你仍然 return this
?!
当动态创建的回调中需要对象时,将上下文放入局部变量很有用。
render: function() {
var that = this; // this is available here
setTimeout(function() {
// here this is not available.
that.handleCallback();
}, 10);
// here we are in the same context as the first line.
return this;
}