一直在阅读 Backbone.js,他们给出了这个例子。
var Sidebar = Backbone.Model.extend({
promptColor: function() {
var cssColor = prompt("Please enter a CSS color:");
this.set({color: cssColor});
}
});
window.sidebar = new Sidebar;
sidebar.on('change:color', function(model, color) {
$('#sidebar').css({background: color});
});
sidebar.set({color: 'white'});
sidebar.promptColor();
提示要求您输入一种颜色,当您输入一种颜色时,边栏的颜色会发生变化。我的问题是,为什么我应该更喜欢上面的代码而不是下面的代码?我认为这与代码结构有关,但我不能确切地说出原因。是不是因为这个例子太简单了,写上面代码的优势只有在应用变大的时候才会体现出来?
忽略用于初始化起始颜色和调用 promptColor()
的主干代码,我将它留在那里作为上下文。
function promptColor(){
var cssColor = prompt("please enter a css color:");
$('#sidebar').css({background:cssColor})
}
最佳答案
首先,给出的示例是一个糟糕的示例,显示了模型内部的 DOM
操作......!不,那不是您操作 DOM
的地方。
需要注意的关键是,backbone 为您的应用程序提供结构,让您轻松分离关注点。
如果您看到下面的示例(又是一个糟糕的边栏示例),表示逻辑完全由 Backbone.View
处理实例。
- 它是一个独立的实例,你可以创建n个
- Backbone 为您创建了具有指定属性的 DOM 元素
- Backbone 使设置委托(delegate)事件处理程序变得非常容易
- Backbone 使得在创建边栏实例时定义要运行的初始化代码变得非常容易
- 我们不必遍历整个
DOM
,并且由于我们在其中处理每个 View 的元素,因此发生冲突的可能性非常小。 - 您只需执行
instance.remove()
即可从DOM
中删除事件处理程序和元素 - 还有很多more
组件的状态和相关数据存储在 Backbone.Model
实例中。
- 让您定义初始状态
- 可以轻松设置初始化逻辑
- 事件使处理数据更改变得容易
- 让您验证对数据的更改
- 让您轻松地与后端同步数据
- 还有很多more
var Color = Backbone.Model.extend({
defaults: {
color: 'white',
accepted: ['white', 'red', 'green', 'blue']
},
validate: function(attrs) {
if (this.get("accepted").indexOf(attrs.color) < 0)
return new Error();
}
});
var Sidebar = Backbone.View.extend({
attributes: {
class: 'sidebar'
},
initialize: function() {
this.listenTo(this.model, 'change:color', this.switchColor);
this.render();
},
events: {
'input .color': 'updateColor',
'click .close': 'remove'
},
render: function() {
this.$el.append($('#sidebar').html());
return this;
},
updateColor: function(e) {
this.model.set({
color: $(e.target).val()
}, {
validate: true
});
},
switchColor: function(model, color) {
this.$el.css({
background: color
});
}
});
for (var i = 0; i < 3; i++) {
$('body').append(new Sidebar({
model: new Color()
}).el);
}
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%
}
.sidebar {
display: inline-block;
box-sizing: border-box;
position: relative;
height: 100%;
padding: 5px 15px 5px 0;
margin: 0 2px;
border: 5px solid dodgerblue
}
.close {
display: inline-block;
position: absolute;
top: 5px;
right: 0;
height: 18px;
text-decoration:none;
border: 0px solid grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
<script type="text/template" id="sidebar">
<input type="text" class="color" placeholder="enter bg color... red, green, blue"/>
<a href="#" class="close">✖</a>
</script>
当然,在此特定示例中,您可以直接修改颜色而无需将其设置为模型,重点是展示如何在实际应用程序中分离组件的关注点。
模型的工作是保存数据并确保它始终有效。 View 将数据呈现给用户并让他使用它。模型作为真相的来源。
如果你使用纯 js,你会发现你的数据和 DOM
是紧密耦合的,你将不得不为 backbone 提供的大量现成的东西编写自定义逻辑。 .. 就像它是事件系统... 路由器... 集合... 同步 API..(我们没有使用它们中的任何一个,除了很少使用事件系统,这就是为什么它是一个糟糕的例子)
回答你的问题:“是不是因为这个例子太简单了” - 是。人们通常不会追求 MV* js 框架来设置提示...这就像用手榴弹打开像亚历山大提到的塑料门。
当您想执行 CRUD 操作、处理路由、与后端通信等时,您会看到 Backbone 表现出色。例如,发送最新颜色(无论是任何数据)您需要做的一切是在模型声明中添加一个 url
属性,并调用 model.save()
。这有多酷……?
关于javascript - Backbone.js 代码与常规 JS 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34315290/