我最近开始学习了backbone.js
。我发现它很棒;我认为保持代码整洁和结构良好是非常有用和优雅的。
在实现了经典todo
应用程序之后,我尝试设计一个简单的应用程序。我认为计算器可能是一个很好的例子。
最有问题的部分是视图。我使用单个视图来侦听按钮上的单击事件,然后更新输出元素(计算器的屏幕)。该模型提供基本运算(例如加法和减法)并仅存储结果。
然而,当我开始实施时,问题就出现了。视图能够检测到单击事件,但无法识别单击了哪个按钮。
首先,您认为我的设计正确吗?如何识别正确的按钮?(代码在文末)
有两个视图会更好吗,一个控制按钮,一个用于每个按钮?例如,一个按钮可能会在其自身上侦听一个单击事件,然后触发另一个带有其编号的事件,然后被另一个视图捕获?
任何建议都非常感谢。:D
这是代码:
索引.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Backbone.js • Calculator</title>
<link rel="stylesheet" href="css/base.css">
</head>
<body>
<section id="calculatorApp">
<header id="header">
<h1>CalculatorJS</h1>
<div id="output">Result</div>
</header>
<section id="buttons">
<div class='button'>1</div>
<div class='button'>2</div>
<div class='button'>3</div>
<div class='button'>4</div>
<div class='button'>5</div>
<div class='button'>6</div>
<div class='button'>7</div>
<div class='button'>8</div>
<div class='button'>9</div>
</section>
</section>
<script src="js/lib/jquery.js"></script>
<script src="js/lib/underscore.js"></script>
<script src="js/lib/backbone.js"></script>
<script src="js/lib/backbone.localStorage.js"></script>
<script src="js/views/calculator.js"></script>
<script src="js/model/calc.js"></script>
<script src="js/app.js"></script>
</body>
</html>
AppView.js
var app = app || {};
app.AppView = Backbone.View.extend({
el: '#calculatorApp',
events:{
'click .button':'update_output'
},
initialize: function () {
this.$output = this.$('#output');
this.$buttons = this.$('#buttons');
console.log("Initialize function AppView");
},
update_output:function(symbol){
console.log("Update output : " + symbol);
console.log(symbol);
},
click:function () {
console.log("click");
}
},
// Class properties
{
NUMBERS:10
}
);
====== 编辑 =======
正如 Colin 所建议的,使用even.target
I 可以检索已单击的按钮。
但是,我更关心应用程序的设计,所以我决定将视图分解为两个解耦的视图。AppView 是外部视图,而 ButtonView 是与按钮关联的视图。这种设计需要一种在单击按钮时通知外部视图的方法。我认为最好的解决方案应该是使用专用事件“clickOn”。当用户单击按钮时,onClick
ButtonView 会触发该事件。AppView 监听此事件并在收到时更新输出。为了实现这个结果,我不得不vent
在应用程序命名空间中引入一个额外的对象 ( ),以便 AppView 和 ButtonView 可以使用相同的事件。
这是一个更好的设计,因为我可以在没有任何副作用的情况下交换意见吗?
这是我介绍的更改:
var app = app || {};
app.ButtonView = Backbone.View.extend({
tagName: 'div',
className : 'button',
events:{
'click' : 'onClick'
},
template: _.template($('#button-template').html()),
initialize:function() {
console.log("Initialize button : " + this.model.symbol);
},
render: function () {
console.log("Render function");
this.$el.html(this.template( {"symbol" : this.model.symbol}));
return this;
},
onClick: function () {
console.log("Hi, I am " + this.model.symbol);
app.vent.trigger("clickOn", this.model.symbol);
}
});
活动:
app.vent = _.extend({}, Backbone.Events);
AppView.js:
app.AppView = Backbone.View.extend({
el: '#calculatorApp',
events:{
},
initialize: function () {
this.$output = this.$('#output');
this.$buttons = this.$('#buttons');
console.log("Initialize function AppView");
this.createNumericButtons();
ttonView({model:new_model});
this.$buttons.append(b this.listenTo(app.vent, 'clickOn', this.update_output)
},
createNumericButtons:function(){
for (var i=0; i< app.AppView.NUMBERS; i++){
var new_model = {symbol:i};
var button = new app.Buutton.render().el);
}
},
update_output:function(symbol){
console.log("Update output : " + symbol);
this.$output.html(symbol);
},
click:function () {
console.log("click");
}
},
// Class properties
{
NUMBERS:10
}
);