我有UserModel
:UserView
和UserCollection
:UserCollectionView
。有了这个,我试图将click
事件绑定到UserView
(我在UserView
中这样做)。所以,这是我的代码:
var root = 'http://localhost:5000/api/v1';
var app = {};
// Backbone Model
app.UserModel = Backbone.Model.extend({
defaults: {
// urlRoot: root + '/users',
name: 'Default Name',
email: '30',
username: 'default_username'
},
initialize: function() {
this.set({
id: this.get('username')
});
console.log('User model \'' + this.id + '\' has been initialized.');
},
// parse: function(data) {
// console.log('Model parse funciton called');
// return data;
// }
});
// Backbone Model View
app.UserView = Backbone.View.extend({
// el: '#users-list',
// tagName: 'div',
el: '.user-box-wrapper',
events: {
'click .user-data': 'userClicked'
},
userClicked: function(ev) {
console.log("User selected");
// console.log(ev.currentTarget);
},
template: _.template($('#connections-user-template').html()),
initialize: function() {
this.render();
},
render: function() {
$('#users-list').append(this.template(this.model.toJSON()));
// this.$el.append( this.template( this.model.toJSON()));
console.log('User view is rendered');
}
});
// Backbone Collection
app.UserCollection = Backbone.Collection.extend({
model: app.UserModel,
url: root + '/users',
initialize: function() {
// this.fetch();
},
parse: function(data) {
// console.log(data.data);
return data.data;
}
});
// Backbone Collection View
app.UserCollectionView = Backbone.View.extend({
el: '#users-list',
template: _.template($('#connections-template').html()),
initialize: function() {
this.connections = new app.UserCollection();
var self = this;
this.connections.fetch().done(function() {
self.render();
});
},
render: function() {
console.log('User collection view is rendered');
this.$el.html(this.template());
// this.$el.append( this.template( this.model.toJSON()));
this.connections.each(function(user) {
console.log('User : ' + user.get('id'));
var userView = new app.UserView({
model: user
});
// userView.model.fetch();
// userView.render();
});
}
});
var connectionsView = new app.UserCollectionView();
JSON数据实际上返回14个对象(在本例中为UserModels)。问题是,如果我点击第一个用户视图,它会被触发13次,第二个视图点击会被触发12次,依此类推,点击时根本没有触发最后一个视图点击事件。
各个UserViews每次都会呈现一次(但至少我认为是这样)。有人可以解释这里的问题是什么以及这里到底发生了什么?
P.S。 - 我知道在CollectionView中绑定事件的解决方法。
修改1
这是DOM结构:
<!doctype html>
<html>
<head>
<title>Hey there</title>
<link rel="stylesheet" href="../static/css/normalize.css">
<link rel="stylesheet" href="../static/css/index.css">
<script src="/static/js/jquery-2.2.0.js"></script>
<script src="/static/js/underscore-1.8.3.js"></script>
<script src="/static/js/backbone-1.2.3.js"></script>
</head>
<body>
<header id="top">
<div id="logo-wrapper">
<img src="../static/img/logo.png" alt="Logo" id="logo">
</div>
<div id="top-links">
<div id="top-profile-box" class="toplink">
<div id="top-profile-data-box">
<div id="top-profile-data-name">Kevin Isaac</div>
<div id="top-profile-data-passion">Writer</div>
</div>
<img id="top-profile-image" src="../static/img/user1.jpg" alt="">
</div>
<div id="notification-icon" class="toplink"></div>
<div id="top-message-icon" class="toplink"></div>
<div id="logout-icon" class="toplink"></div>
</div>
</header>
<div id="middle">
<nav id="side-nav">
<div id="side-nav-top">
<div class="side-nav-link" id="side-nav-home-link">
<div class="side-nav-link-img"></div>
<div class="side-nav-link-title">Home</div>
</div>
<div class="side-nav-link" id="side-nav-profile-link">
<div class="side-nav-link-img"></div>
<div class="side-nav-link-title">Profile</div>
</div>
<div class="side-nav-link" id="side-nav-messages-link">
<div class="side-nav-link-img"></div>
<div class="side-nav-link-title">Message</div>
</div>
<div class="side-nav-link" id="side-nav-account-link">
<div class="side-nav-link-img"></div>
<div class="side-nav-link-title">Account</div>
</div>
</div>
</nav>
<div id="main-content">
<!-- Start of page specific HTML -->
<div id="content-title">
<div class="content-subtitle" id="connections">Connections</div>
<div class="content-subtitle" id="followers">Followers</div>
<div class="content-subtitle" id="followings">Followings</div>
</div>
<div id="content-body">
<div id="users-box">
<div id="users-list">No connection</div>
<!-- Backbone Template Starts -->
<script type="text/template" id="connections-template"></script>
<script type="text/template" id="connections-user-template">
<div class="user-box-wrapper">
<div class="user-box">
<div class="user-pic-wrapper">
<img src="/static/img/user1.jpg" alt="">
</div>
<div class="user-data" id="boox">
<div class="user-name"><%= name %></div>
<div class="user-passion"><%= username %></div>
<div class="user-city"><%= email %></div>
</div>
</div>
</div>
</script>
<!-- Backbone Template Ends -->
<div id="users-side-box">
<div id="users-box-search">
<input id="user-search" type="text" name="">
</div>
<div id="user-metadata">
<div id="metadata-user-top-box">
<div id="metadata-user-image-wrapper">
<img src="/static/img/user1.jpg" alt="">
</div>
<div id="metadata-user-name-box">
<div id="metadata-name">Name's Bond</div>
<div id="metadata-passion">Assassin</div>
</div>
</div>
<div id="metadata-user-bottom-box">
<div class="metadata-user-attribute">
<span class="metadata-property">Studied at: </span>
<span class="metadata-value">Karunya University </span>
</div>
<div class="metadata-user-attribute">
<span class="metadata-property">Native City: </span>
<span class="metadata-value">London</span>
</div>
<div class="metadata-user-attribute">
<span class="metadata-property">Website: </span>
<span class="metadata-value">www.007.com</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- End of page specific HTML -->
</div>
<aside id="main-aside">
Aside one two therr
</aside>
</div>
<script src="../static/js/index.min.js"></script>
</body>
</html>
答案 0 :(得分:2)
您的代码存在许多问题。
主要问题是,所有userView都指向同一个选择器,与此选择器.user-box-wrapper
匹配的元素位于视图模板内 - 因此,无论何时创建新的userView,它都会添加一个新事件监听器.user-box-wrapper
存在于所有现有的userViews中,但不归于自身。因此,您的第一个userView将向其注册n-1
个事件处理程序,而最后一个没有(n
是userViews的总数)。视图元素不应该是模板的一部分,模板应该被添加到视图元素中。
如果您的视图将拥有自己的多个副本,请不要定义el
选项,让骨干为视图的每个实例创建一个新元素。您可以自定义此元素的属性。
另一个问题是你没有将userView模板附加到你的userView元素,而是在它之外的其他东西($('#users-list')
。所以点击模板不会触发事件处理程序(在你的情况下这就是你的原因) '最后一个userView没有触发它的事件。它被绑定到所有其他现有视图,因为公共选择器是由el
提供的)
您应该尝试在视图中避免使用$('#users-list')
等全局选择器。在这种情况下,您可以在userCollectionView中将userView附加到#users-list
,其中elc指向#users-list
。
您的代码应为:
var root = 'http://localhost:5000/api/v1';
var app = {};
// Backbone Model
app.UserModel = Backbone.Model.extend({
defaults: {
// urlRoot: root + '/users',
name: 'Default Name',
email: '30',
username: 'default_username'
},
initialize: function() {
this.set({
id: this.get('username')
});
console.log('User model \'' + this.id + '\' has been initialized.');
}
});
// Backbone Model View
app.UserView = Backbone.View.extend({
className: 'user-box-wrapper',
/*--^-- creates a new div with this class for each user*/
template: _.template($('#connections-user-template').html()),
events: {
'click .user-data': 'userClicked'
},
initialize: function() {
this.render();
},
render: function() {
this.$el.append( this.template( this.model.toJSON()));
console.log('User view is rendered');
},
userClicked: function(ev) {
console.log("User selected");
// console.log(ev.currentTarget);
}
});
// Backbone Collection
app.UserCollection = Backbone.Collection.extend({
model: app.UserModel,
url: root + '/users',
initialize: function() {
// this.fetch();
},
parse: function(data) {
// console.log(data.data);
return data.data;
}
});
// Backbone Collection View
app.UserCollectionView = Backbone.View.extend({
el: '#users-list',
template: _.template($('#connections-template').html()),
initialize: function() {
this.connections = new app.UserCollection();
var self = this;
this.connections.fetch().done(function() {
self.render();
});
},
render: function() {
this.$el.html(this.template());
console.log('User collection view is rendered');
this.connections.each(function(user) {
console.log('User : ' + user.get('id'));
var userView = new app.UserView({
model: user
});
this.$el.append(userView.el); /*append child view here*/
},this);
}
});
var connectionsView = new app.UserCollectionView();
答案 1 :(得分:-1)
主要问题是您在同一容器中呈现所有 UserView 视图:
$('#users-list').append(this.template(this.model.toJSON()));
这就是点击事件选择器('click .user-data')正在选择其他 UserView 按钮并触发其点击的原因。
你没有问,但......这里有一些建议:
这是一个我认为你想要的jsfiddle: https://jsfiddle.net/Neviton/n52j873u/