0

我正在获取一个在 Backbonejs 视图中使用 Easeljs 创建的简单绘图视图。我在侦听器事件中遇到范围问题,例如:

this.stage.addEventListener("stagemousedown", this.handleMouseDown);

我开始这样做是为了解决我的范围问题

var self = this;
this.stage.addEventListener("stagemousedown", function(){
    var foo = self.bar;
});

但是,这似乎很草率,特别是因为我正在移植的示例代码 ( http://www.createjs.com/#!/EaselJS/demos/drawing ) 具有嵌套级别的 eventListener。

SketchView = Backbone.View.extend({


initialize: function(){
   this.canvas;
   this.stage;
   this.drawingCanvas;
   this.oldPt;
   this.oldMidPt;
   this.title;
   this.color;
   this.stroke;
   this.colors;
   this.index;
},

beforeRender : function (){
    this.template = _.template( tpl.get(this.templateFile) );
},

render: function(eventName) {
   $(this.el).html(this.template(this.model));
   return this;
},

//add in UI
afterRender : function (){
    this.createUI();
},

createUI: function() {
    this.canvas = document.getElementById("demoCanvas");
    this.index = 0;
    this.colors = ["#828b20", "#b0ac31", "#cbc53d", "#fad779", "#f9e4ad", "#faf2db", "#563512", "#9b4a0b", "#d36600", "#fe8a00", "#f9a71f"];

    //Create a stage by getting a reference to the canvas
    this.stage = new createjs.Stage(this.canvas);
    this.stage.autoClear = false;
    this.stage.enableDOMEvents(true);

    createjs.Touch.enable(this.stage);
    createjs.Ticker.setFPS(24);

    this.stage.addEventListener("stagemousedown", this.handleMouseDown);
    this.stage.addEventListener("stagemouseup", this.handleMouseUp);

    this.title = new createjs.Text("Click and Drag to draw", "36px Arial", "#777777");
    this.title.x = 300;
    this.title.y = 200;
    this.stage.addChild(this.title);

    this.stage.addChild(this.drawingCanvas);
    this.stage.update();
 },

handleMouseDown: function (event) {
        if (this.stage.contains(this.title)) { this.stage.clear(); this.stage.removeChild(this.title); }
        this.color = this.colors[(this.index++)%this.colors.length];
        this.stroke = Math.random()*30 + 10 | 0;
        this.oldPt = new createjs.Point(this.stage.mouseX, this.stage.mouseY);
        this.oldMidPt = this.oldPt;
        this.stage.addEventListener("stagemousemove" , this.handleMouseMove);
    },

   handleMouseMove: function (event) {
        var midPt = new createjs.Point(this.oldPt.x + this.stage.mouseX>>1, this.oldPt.y+this.stage.mouseY>>1);

        this.drawingCanvas.graphics.clear().setStrokeStyle(this.stroke, 'round', 'round').beginStroke(this.color).moveTo(midPt.x, midPt.y).curveTo(this.oldPt.x, this.oldPt.y, this.oldMidPt.x, this.oldMidPt.y);

        this.oldPt.x = this.stage.mouseX;
        this.oldPt.y = this.stage.mouseY;

        this.oldMidPt.x = midPt.x;
        this.oldMidPt.y = midPt.y;

        this.stage.update();
    },

    handleMouseUp: function (event) {
        this.stage.removeEventListener("stagemousemove" , this.handleMouseMove);
    }

});

一个不相关的问题,我应该在初始化函数中实例化我的变量吗?我仍然是 Backbone 的新手,并试图找出最佳实践。

4

1 回答 1

2

Backbone 需要 Underscore 库,我强烈建议您熟悉它:它有很多很棒的东西。特别是它有一个_.bind你可以像这样使用的方法:

this.stage.addEventListener("stagemousedown", _(function(){
    var foo = this.bar; // "this" will be correct now thanks to bind
}).bind(this);

它还有一个相关的_.bindAll方法,可用于(通常在initialize函数内部)将对象的方法绑定到它,如下所示:

initialize: function() {
    _(this).bindAll('handleMouseDown'); // handleMouseDown's this will be correct
    this.stage.addEventListener("stagemousedown", this.handleMouseDown);
}

但是,如果您只是利用它的事件处理,您可以避免所有这些并让 Backbone 为您完成绑定:

Backbone.View.extend({
    events: {mousedown: 'handleMouseDown'}
    handleMouseDown: function() {
        // this will be bound correctly

至于您关于在内部实例化变量的问题initialize,答案是......可能,但如果不知道您的具体上下文就很难说。一般来说,initialize应该在创建集合/模型/视图时做任何需要发生的事情,所以如果初始化变量属于这个范围,那么可以确定。

于 2013-03-15T05:33:45.097 回答