Backbone.js视图基础 #
一、什么是View #
View(视图)是Backbone.js中负责渲染UI和处理用户交互的组件。
1.1 View的作用 #
text
View职责
├── 渲染UI:将模型数据渲染为HTML
├── 事件处理:处理用户交互事件
├── 模型绑定:监听模型变化并更新UI
├── DOM操作:操作DOM元素
└── 子视图管理:管理子视图的生命周期
1.2 View的双重角色 #
Backbone的View同时承担视图和控制器的职责:
text
View = View(视图) + Controller(控制器)
视图职责:
├── 渲染HTML
├── 更新UI
└── 显示数据
控制器职责:
├── 处理用户输入
├── 更新模型
└── 协调视图和模型
二、创建View #
2.1 基本创建方式 #
javascript
var UserView = Backbone.View.extend({
render: function() {
this.$el.html('<h1>Hello Backbone!</h1>');
return this;
}
});
var view = new UserView();
view.render();
$('#app').html(view.el);
2.2 initialize方法 #
javascript
var UserView = Backbone.View.extend({
initialize: function(options) {
console.log('视图已创建');
console.log('选项:', options);
this.listenTo(this.model, 'change', this.render);
}
});
var user = new Backbone.Model({ name: '张三' });
var view = new UserView({ model: user });
2.3 传递选项 #
javascript
var UserView = Backbone.View.extend({
initialize: function(options) {
this.customOption = options.customOption;
}
});
var view = new UserView({
model: user,
collection: users,
customOption: '自定义选项'
});
三、el属性 #
3.1 什么是el #
el 是视图的根DOM元素,所有视图操作都基于这个元素。
javascript
var view = new Backbone.View({
el: '#app'
});
console.log(view.el);
console.log(view.$el);
3.2 el vs $el #
| 属性 | 类型 | 说明 |
|---|---|---|
| el | DOM Element | 原生DOM元素 |
| $el | jQuery Object | jQuery包装对象 |
3.3 使用现有元素 #
javascript
var UserView = Backbone.View.extend({
el: '#app',
render: function() {
this.$el.html('<h1>Hello</h1>');
return this;
}
});
var view = new UserView();
view.render();
3.4 创建新元素 #
javascript
var UserView = Backbone.View.extend({
tagName: 'div',
className: 'user-item',
id: 'user-1',
attributes: {
'data-role': 'user'
},
render: function() {
this.$el.html('<span>用户信息</span>');
return this;
}
});
var view = new UserView();
console.log(view.el.outerHTML);
3.5 tagName、className、id #
javascript
var UserView = Backbone.View.extend({
tagName: 'li',
className: 'user-item active',
id: 'user-item-1'
});
var view = new UserView();
console.log(view.el.outerHTML);
3.6 动态属性 #
javascript
var UserView = Backbone.View.extend({
tagName: 'div',
attributes: function() {
return {
'class': 'user user-' + this.model.id,
'data-user-id': this.model.id
};
}
});
var user = new Backbone.Model({ id: 1, name: '张三' });
var view = new UserView({ model: user });
console.log(view.el.outerHTML);
四、render方法 #
4.1 基本渲染 #
javascript
var UserView = Backbone.View.extend({
render: function() {
this.$el.html('<h1>' + this.model.get('name') + '</h1>');
return this;
}
});
var user = new Backbone.Model({ name: '张三' });
var view = new UserView({ model: user });
$('#app').html(view.render().el);
4.2 返回this #
javascript
var UserView = Backbone.View.extend({
render: function() {
this.$el.html('<h1>Hello</h1>');
return this;
}
});
var view = new UserView();
view.render().$el.appendTo('#app');
4.3 使用模板 #
javascript
var UserView = Backbone.View.extend({
template: _.template(
'<div class="user">' +
' <h2><%= name %></h2>' +
' <p><%= email %></p>' +
'</div>'
),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var user = new Backbone.Model({
name: '张三',
email: 'zhangsan@example.com'
});
var view = new UserView({ model: user });
view.render();
4.4 渲染集合 #
javascript
var UserListView = Backbone.View.extend({
tagName: 'ul',
render: function() {
this.$el.empty();
this.collection.each(function(user) {
var userView = new UserView({ model: user });
this.$el.append(userView.render().el);
}, this);
return this;
}
});
五、$方法 #
5.1 查找元素 #
javascript
var UserView = Backbone.View.extend({
template: _.template(
'<div class="user">' +
' <h2 class="name"><%= name %></h2>' +
' <p class="email"><%= email %></p>' +
'</div>'
),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
updateName: function(name) {
this.$('.name').text(name);
},
updateEmail: function(email) {
this.$('.email').text(email);
}
});
5.2 $ vs jQuery #
javascript
var UserView = Backbone.View.extend({
el: '#app',
render: function() {
this.$el.html('<div class="item">Item</div>');
var $item1 = this.$('.item');
var $item2 = $('#app .item');
console.log($item1.length);
console.log($item2.length);
}
});
六、视图选项 #
6.1 标准选项 #
javascript
var view = new Backbone.View({
model: user,
collection: users,
el: '#app',
id: 'my-view',
className: 'my-class',
tagName: 'div',
attributes: { 'data-test': 'value' }
});
6.2 自定义选项 #
javascript
var UserView = Backbone.View.extend({
initialize: function(options) {
this.title = options.title || '默认标题';
this.editable = options.editable !== false;
}
});
var view = new UserView({
model: user,
title: '用户详情',
editable: true
});
七、视图生命周期 #
7.1 创建阶段 #
javascript
var UserView = Backbone.View.extend({
initialize: function() {
console.log('1. 视图初始化');
this.listenTo(this.model, 'change', this.render);
},
render: function() {
console.log('2. 视图渲染');
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
7.2 销毁视图 #
javascript
var UserView = Backbone.View.extend({
remove: function() {
this.stopListening();
this.undelegateEvents();
this.$el.remove();
return this;
}
});
7.3 清理资源 #
javascript
var UserView = Backbone.View.extend({
initialize: function() {
this.childViews = [];
this.listenTo(this.model, 'change', this.render);
},
remove: function() {
this.childViews.forEach(function(child) {
child.remove();
});
this.stopListening();
this.undelegateEvents();
Backbone.View.prototype.remove.call(this);
}
});
八、实用示例 #
8.1 用户卡片视图 #
javascript
var UserCardView = Backbone.View.extend({
tagName: 'div',
className: 'user-card',
template: _.template(
'<div class="card">' +
' <img src="<%= avatar %>" class="avatar">' +
' <h3 class="name"><%= name %></h3>' +
' <p class="email"><%= email %></p>' +
' <button class="btn-edit">编辑</button>' +
'</div>'
),
events: {
'click .btn-edit': 'edit'
},
initialize: function() {
this.listenTo(this.model, 'change', this.render);
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
edit: function() {
console.log('编辑用户:', this.model.get('name'));
}
});
8.2 列表项视图 #
javascript
var TodoItemView = Backbone.View.extend({
tagName: 'li',
className: 'todo-item',
template: _.template(
'<input type="checkbox" <%= completed ? "checked" : "" %>>' +
'<span class="title"><%= title %></span>' +
'<button class="delete">×</button>'
),
events: {
'click input[type="checkbox"]': 'toggle',
'click .delete': 'clear'
},
initialize: function() {
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'destroy', this.remove);
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
this.$el.toggleClass('completed', this.model.get('completed'));
return this;
},
toggle: function() {
this.model.toggle();
},
clear: function() {
this.model.destroy();
}
});
8.3 表单视图 #
javascript
var UserFormView = Backbone.View.extend({
tagName: 'form',
className: 'user-form',
template: _.template(
'<div class="form-group">' +
' <label>姓名</label>' +
' <input type="text" name="name" value="<%= name %>">' +
'</div>' +
'<div class="form-group">' +
' <label>邮箱</label>' +
' <input type="email" name="email" value="<%= email %>">' +
'</div>' +
'<button type="submit">保存</button>'
),
events: {
'submit': 'submit',
'input input': 'updateModel'
},
initialize: function() {
this.listenTo(this.model, 'change', this.render);
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
updateModel: function(e) {
var $input = $(e.target);
this.model.set($input.attr('name'), $input.val());
},
submit: function(e) {
e.preventDefault();
this.model.save();
}
});
九、总结 #
9.1 View核心属性 #
| 属性 | 说明 |
|---|---|
| el | 根DOM元素 |
| $el | jQuery包装的根元素 |
| model | 关联的模型 |
| collection | 关联的集合 |
| events | 事件映射 |
| template | 模板函数 |
9.2 View核心方法 #
| 方法 | 说明 |
|---|---|
| initialize | 初始化方法 |
| render | 渲染方法 |
| remove | 移除视图 |
| $(selector) | 在视图内查找元素 |
| delegateEvents | 绑定事件 |
| undelegateEvents | 解绑事件 |
9.3 最佳实践 #
- 始终在
render方法中返回this - 使用
listenTo绑定模型事件 - 在
remove中清理资源 - 使用模板引擎分离HTML
- 保持视图职责单一
最后更新:2026-03-28