在Backbone.js中使用View Render重复时丢失范围

时间:2012-10-16 11:04:14

标签: backbone.js

我是Backbone.js的新手,我正在通过一个简单的视图来看待范围问题&模型场景。

我创建了一个简单的模型,其中包含一个默认的“得分”值。我还创建了一个简单的视图,其中包含模板渲染值“得分”和一个按钮,以便在每次按下时将得分增加1。每次更改分数值时,视图都会重复渲染。

我有这个工作,但我认为可能是一个拙劣的方式。除非我在视图变量“thisView”中缓存“this”的值,否则模板将仅第一次呈现。如果我不这样做,它似乎失去焦点和渲染错误。这是一个好主意吗?或者我错过了重复应用渲染的内容。

感谢您的任何建议

<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
    <style>
       #view_container{background-color: rgba(12, 5, 11, 0.14);width: 100px;height: 100px;padding: 10px;}
    </style>
</head>
<body>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script>

<!-- View Template -->
<script type="text/template" id="view-template">
    <div class="profileSpace">
        <p>Score: <%= score %></p>
    </div>
    <button id="increaseScoreButton">Increase Score</button>
</script>

<div id="view_container"></div>

<script type="text/javascript">
(function ($) {


MyModel = Backbone.Model.extend({
    defaults:{
        score:0
    },
    initialize: function(){

    },
    increaseScore: function(){

        //Increase Score by 1

        var currentScore = this.get("score");

        var newScore = currentScore +1;

        this.set({score:newScore});

    }
});

MyView = Backbone.View.extend({

        el: $("#view_container"),

        template: _.template($('#view-template').html()),

        initialize: function(model){

                thisView =this;

                this.model.bind('change', this.render, this);

                this.render();

            },
        events: {

            "click #increaseScoreButton":  "increaseScore"

        },

        increaseScore: function(){

            this.model.increaseScore();

        },
        render: function(){

            var currentScore = thisView.model.get("score");

            var html = thisView.template({"score":currentScore});

            $(thisView.el).html( html );
            return thisView;
        }
    });

myModel = new MyModel;
myApp = new MyView({model:myModel});

})(jQuery);

</script>

</body>
</html>

1 个答案:

答案 0 :(得分:1)

您通过change

绑定this.model.bind('change', this.render, this);事件

此语法为introduced in Backbone 0.5.2,但您在示例中使用了Backbone 0.3.3。

  

0.5.2 - 2011年7月26日
  bind函数现在可以使用可选的第三个参数来指定回调函数的这个参数。

将Backbone升级到更新的版本(截至今天为0.9.2),你应该得到预期的行为。

或者,正如CoryDanielson在评论中指出的那样,你可以使用_.bindAll来保证上下文:

MyView = Backbone.View.extend({
    initialize: function(model) {
        _.bindAll(this, 'render');
        this.model.bind('change', this.render);
        this.render();
    },

    render: function(){
        var currentScore = this.model.get("score");
        var html = this.template({"score":currentScore});
        $(this.el).html( html );
        return this;
    }
});