0

我最近开始学习了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.targetI 可以检索已单击的按钮。

但是,我更关心应用程序的设计,所以我决定将视图分解为两个解耦的视图。AppView 是外部视图,而 ButtonView 是与按钮关联的视图。这种设计需要一种在单击按钮时通知外部视图的方法。我认为最好的解决方案应该是使用专用事件“clickOn”。当用户单击按钮时,onClickButtonView 会触发该事件。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
    }
);
4

1 回答 1

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

于 2013-09-14T15:50:04.753 回答