一个带BackBone.js的小型计算器

时间:2013-09-14 15:06:24

标签: javascript jquery design-patterns model-view-controller backbone.js

我最近开始研究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
    }
);

1 个答案:

答案 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应用程序感兴趣,我认为这将是一个很好的练习。