Javascript 未捕获类型错误:视图不是构造函数
我有一个未捕获的类型错误:UserRegisterView不是构造函数。我不理解这个错误。我查看了所有代码,但没有找到它。 对不起,我英语不好,请帮帮我 谢谢你的回答 已更新 UserRegisterView在这里Javascript 未捕获类型错误:视图不是构造函数,javascript,jquery,backbone.js,Javascript,Jquery,Backbone.js,我有一个未捕获的类型错误:UserRegisterView不是构造函数。我不理解这个错误。我查看了所有代码,但没有找到它。 对不起,我英语不好,请帮帮我 谢谢你的回答 已更新 UserRegisterView在这里 var UserRegisterView=Backbone.View.extend({ 型号:用户, el:'表格', 活动:{ '单击输入[id=“infoWeek”]:'infoWeek', '单击输入[id=“infoMonth”]:'infoMonth' }, infoWee
var UserRegisterView=Backbone.View.extend({
型号:用户,
el:'表格',
活动:{
'单击输入[id=“infoWeek”]:'infoWeek',
'单击输入[id=“infoMonth”]:'infoMonth'
},
infoWeek:function(){
这个.el.find(“#dayOfMonth”).hide();
这个。render();
},
infoMonth:function(){
此.el.find(“#dayOfWeek”).hide();
这个。render();
}
});
var AddUserView=Backbone.View.extend({
el:$(“.page”),
活动:{
'单击#saveUser':'saveUser'
},
saveUser:function(){
var user=新用户();
user.set({
用户名:$(“#用户名”).val(),
lastName:$(“#lastName”).val(),
regNumber:$(“#regNumber”).val(),
密码:$(“#密码”).val(),
部门名称:$(“#部门名称”).val(),
电子邮件:$(“#电子邮件”).val(),
角色:$(“#角色”).val()
});
user.save();
if(document.getElementById('isOpen')。选中){
user.set(“isOpen”,$(“#isOpen”).val(“1”);
user.save();
}否则{
user.set(“isOpen”,$(“#isOpen”).val(“0”);
user.save();
}
if(document.getElementById('dayOfWeek')。选中){
user.set(“dayOfWeek”,$(“#dayOfWeek”).val();
user.save();
}else if(document.getElementById('dayOfMonth')。选中){
user.set(“dayOfMonth”,$(“#dayOfMonth”).val();
user.save();
}
$(“#用户名”).val(“”);
$(“#firstName”).val(“”);
$(“#lastName”).val(“”);
$(“#regNumber”).val(“”);
$(“#密码”).val(“”);
$(“#部门名称”).val(“”);
$(“#email”).val(“”);
$(“#isOpen”).val(“”);
$(“#dayOfWeek”).val(“”);
$(“#月日”).val(“”);
},
render:function(){
var=这个;
var template=handlebar.compile(UserRegister);
var myHtml=template(that.model.toJSON());
那.$el.html(myHtml);
归还这个;
}
});
返回{
AddUserView:AddUserView,
UserRegisterView:UserRegisterView
};
});
路由器用户函数
定义([
“jquery”,
“下划线”,
"骨干",,
“把手”,
“旋转”,
“应用程序/模型/登录模型”,
“应用程序/视图/登录视图”,
'应用程序/视图/用户注册视图'
],函数($,
_,
骨干,
车把,
纺纱机,
登录,
LoginView,
用户注册视图
) {
var Router=Backbone.Router.extend({
路线:{
“搜索”:“搜索”,
'login':'login',
‘旅行’:‘旅行’,
“用户”:“用户”,
“菜单”:“菜单”,
“家”
},
用户:函数(){
disposeView(新的UserRegisterView().render());
}
util.js上的dispose.view
功能配置视图(视图){
Backbone.View.prototype.close=函数(){
这个。解除绑定();
此.undelegateEvents();
};
/*Şu anki viewi yok et*/
if(this.currentView!==未定义){
this.currentView.close();
}
/*耶尼视图奥卢图尔*/
this.currentView=视图;
this.currentView.delegateEvents();
返回此.currentView;
}
发生了什么事
您的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
其他改进 也就是说,可以对主干代码进行其他改进
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;
}
不要每次调用函数时都更改默认主干视图原型。相反,只需添加一次函数
_.extend(Backbone.View.prototype, {
close: function() {
this.unbind();
this.undelegateEvents();
},
// any other function you want to add can go here.
});
在另一个回答中,我将详细介绍
您已经在使用jQuery,所以不要使用JavaScript DOM APIdocument.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%的时候我在堆栈溢出问题上看到它,这是没有意义的。它明显地尖叫着复制粘贴
请告诉我,您看到您正在将这个
放入那个
,然后在整个函数中使用那个
,然后仍然返回这个
在动态创建的回调中需要对象时,将上下文放入局部变量非常有用
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
。还有,为什么对user.save()
调用那么多?为什么混合使用getElementById
调用和jQuery调用?很抱歉,编辑错误。我能在一次保存中保存多个文本框吗()方法?和yh混合了一点,但这对我来说很容易。这是个问题吗?但是在retur中仍然有UserView:UserRegisterView
render: function() {
var that = this;
// ...
that.$el.html(myHtml);
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;
}