我最近开始研究backbone.js
。我发现它很棒;我认为保持代码整洁和结构良好是非常有用和优雅的。
在实现经典todo
应用程序之后,我尝试设计一个简单的应用程序。我认为计算器可以是一个很好的例子。
最有问题的部分是视图。我使用一个监听点击事件的视图 一个按钮,然后更新输出元素(计算器的屏幕)。 该模型提供基本操作(例如加法和减法)并仅存储结果。
然而,一旦我开始实施,就会出现问题。该视图能够检测到单击事件,但无法识别单击了哪个按钮。
首先,您认为我的设计是否正确? 如何识别正确的按钮? (代码在帖子的末尾)
有两个视图会更好吗,一个控制按钮,每个按钮一个?例如,按钮可以自己监听点击事件,然后触发另一个事件及其编号,然后由其他观点?
任何建议都值得赞赏。 :d
以下是代码:
index.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
我可以检索已点击的按钮。
但是,我更关注应用程序的设计,所以我决定打破
将视图分成两个分离的视图。 AppView是外部视图,和
ButtonView是与按钮相关联的视图。
这种设计需要一种在按钮通知时通知外部视图的方法
点击。我认为最好的解决方案应该是使用专门的活动&#34; clickOn&#34;。
当用户单击按钮时,ButtonView会触发onClick
事件。
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
}
);
答案 0 :(得分:2)
您可以使用event.target
访问点击的元素,如下所示:
update_output:function(event){
// event.target refers to the clicked element
console.log(event.target);
}
通过JSFiddle简化演示:http://jsfiddle.net/C7PZZ/1/
关于您的整体设计,您的应用程序可能非常简单,单个视图就可以了。但是,我建议您创建一个单独的ButtonView
。将UI分解为更小的部分(即视图)有助于在应用程序变得复杂时保持可管理性。如果您对构建Backbone应用程序感兴趣,我认为这将是一个很好的练习。