如何在Backbone.js中将视图代码分离成模型和控制器
How to separate view code into model and controller in Backbone.js
我有我的代码,这是一个基本的TODO列表,只有下面的代码行。
我面临的问题是,几乎所有的东西都挤在视图本身。模型或集合中几乎没有任何代码行,而且也没有控制器。
这是否定MVC在骨干,这是我试图实现。是否有任何方式,我可以从视图中删除代码,并将其放入任何其他模块?
(function($){
Backbone.sync = function(method, model, success, error){
success();
}
var Item = Backbone.Model.extend({});
var List = Backbone.Collection.extend({
model: Item
});
var ItemView = Backbone.View.extend({
tagName: 'div', // name of tag to be created
events: {
'click span.delete': 'remove'
},
initialize: function(){
_.bindAll(this, 'render', 'unrender', 'remove'); // every function that uses 'this' as the current object should be in here
this.model.bind('change', this.render);
this.model.bind('remove', this.unrender);
},
render: function(){
$(this.el).html("<span style='margin-left: 20px;'></span>"+this.model.get('part')+'<span class="delete" style="cursor:pointer; color:red; font-family:sans-serif;">[delete]</span>');
return this; // for chainable calls, like .render().el
},
unrender: function(){
this.model.destroy();
}
});
var ListView = Backbone.View.extend({
el: $('body'), // attaches `this.el` to an existing element.
events: {
'click button#add': 'addItem'
},
initialize: function(){
_.bindAll(this, 'render', 'addItem'); // fixes loss of context for 'this' within methods
this.collection = new List();
this.collection.bind('add', this.appendItem); // collection event binder
this.render(); // not all views are self-rendering. This one is.
},
render: function(){
var self = this;
$(this.el).append("<body style='margin: 0; padding: 0;' id='body'><div style='margin: 20px;'><h1>TODO list in plain JS and JQuery</h1><input type='text' id='taskBox' autofocus/>");
$(this.el).append("<span id='appendToSpan'></span>");
$(this.el).append("<button style='margin-left: 20px;' id='add'>Add list item</button>");
_(this.collection.models).each(function(item){ // in case collection is not empty
self.appendItem(item);
}, this);
},
addItem: function(){
var item = new Item();
var val = $(this.el).find('input#taskBox').val();
$(this.el).find('input#taskBox').val('');
//this.model.set({'part': val});
item.set({'part': val});
this.collection.add(item);
},
appendItem: function(item){
var itemView = new ItemView({
model: item
});
$('span#appendToSpan', this.el).append(itemView.render().el);
}
});
var listView = new ListView();
})(jQuery);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TODO App</title>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.io/backbone/backbone-min.js"></script>
<script src="views/demo1View.js" type="text/javascript"></script>
</body>
</html>
Backbonejs不是MVC框架。它更像是MVP (P - presenter)框架。换句话说,你可以把你的逻辑驻留在视图中,在真正的MVC框架中扮演控制器的角色。
试着把组件的职责分开,让它尽可能的简单。
我建议对你的代码进行如下重构:
(function($){
Backbone.sync = function(method, model, success, error){
success();
}
var Item = Backbone.Model.extend({});
var List = Backbone.Collection.extend({
model: Item
});
var ItemView = Backbone.View.extend({
events: {
'click .js-delete': 'remove'
},
template: _.template($('#itemViewTemplate').html()),
initialize: function(){
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'remove', this.unrender);
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
unrender: function(){
this.$el.remove();
}
});
var ListView = Backbone.View.extend({
events: {
'click .js-addItem': 'addItem'
},
initialize: function(){
this.listenTo(this.collection, 'add', this.appendItem);
},
render: function(){
this.collection.each(this.appendItem, this);
return this;
},
addItem: function(){
var $input = this.$('input#taskBox')
var val = $input.val();
this.collection.add({part: val});
// clear input
$input.val('');
},
appendItem: function(item){
var itemView = new ItemView({
model: item,
template: this.template
});
this.$('#appendToSpan').append(itemView.render().el);
}
});
// Initialize widget and empty collection
var listView = new ListView({
el: 'body',
collection: new List()
});
// Render collection
listView.render();
})(jQuery);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TODO App</title>
<style>
body {
margin: 0;
padding: 0;
}
.container {
margin: 20px;
}
.addButton {
margin-left: 20px;
margin-top: 10px;
}
.item-name {
margin-left: 20px;
}
.item-remove {
cursor:pointer;
color:red;
font-family:sans-serif;
}
</style>
</head>
<body>
<div class="container">
<h1>TODO list in plain JS and JQuery</h1>
<input type='text' id='taskBox' autofocus/>
<div id='appendToSpan'></div>
<button class="addButton js-addItem">Add list item</button>
<!-- Item template -->
<script type="text/template" id="itemViewTemplate">
<span class="item-name"><%= part %></span>
<span class="js-delete item-remove">[delete]</span>
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.io/backbone/backbone-min.js"></script>
</body>
</html>
相关文章:
- 在Jquery中分离后,如何将相同的函数添加回代码中
- AngularJS中的代码分离
- 在Titanium中分离平台特定代码的最佳方式
- 在不使用jquery($symbol)knockout.js的情况下分离代码javascript
- 使用 IIFE 进行游戏开发 - 代码分离
- 分离AngularJs控制器代码的最佳方法
- 如何分离代码:我的控制器是否做了太多工作
- 有哪些可能的方法可以将 knockoutjs 视图模型代码与 asp.net mvc 视图分离,并对其进行 mvc 服务
- 是否可以将javascript代码与Riot Js中的标记文件分离
- 分离JavaScript代码的缺点
- React.js:将React.js代码与HTML分离
- 发布/订阅后分离文件夹的客户端和服务器的代码
- jQuery.remove(),分离DOM元素,但我仍然可以从代码访问元素.如何避免泄漏
- 如何为网站的不同部分分离javascript代码
- 如何将代码从一个路由文件分离到多个,以及如何从这些分离的文件中调用函数
- 剑道UI - Java脚本事件处理程序(代码分离+参数)
- 如何分离ajax响应和HTML代码
- 如何在Backbone.js中将视图代码分离成模型和控制器
- 可重用的D3图表与公共代码分离
- 如何使用角度不反对分离代码