Backbone.js & raphäel.js/Backbone View ↔ Raphäel Object

И теперь, для чего-то совершенно другого.

Как я могу делегировать события в режиме магистрали, когда объект "dom" объект raphäel. Это вообще работает? Вот так:

var NodeView = Backbone.View.extend({ 
                events: { 
                        "click": "click" 
                }, 
                click: function(){ 
                        alert('clicked') 
                }, 
                render: function(){ 
                        canvas.rect(this.model.get('xPos'), this.model.get('yPos'), 50, 50).attr({ 
                            fill: "#EEEEEE", 
                            stroke: "none", 
                            cursor: "move" 
                        }); 
                        return this; 
                } 

    }); 

Мне нужно обновить модель, когда объект raphäel изменил положение. Когда я привязываю событие прямо к объекту raphäel, у меня есть доступ к этому, а не ко всему виду и, следовательно, к модели.

Ответ 1

Он должен работать, если вы действительно используете элемент DOM. Например. если у вас есть объект Raphael круг, то элемент DOM будет circle.node. Тот, который вам нужно передать как свойство "el" в параметрах или убедиться, что View this.el на самом деле является объектом Raphael "node".

Если вы хотите связать событие вручную и хотите иметь доступ к представлению в обработчике событий, используйте функцию привязки Underscore:

$(circle.node).click(_.bind(someHandlerFunction, this));

где этот должен указывать на объект вида в текущем контексте. В этом случае внутри someHandlerFunction, этот объект будет отображаться.

Ответ 2

Другой способ сделать это - вручную переопределить свойство this.el в конструкторе/инициализаторе представления, используя новый метод View.setElement с ссылка на Raphael Element.node следующим образом:

var NodeView = Backbone.View.extend({ 
    initialize: function (args) {

        // create an empty reference to a Raphael rect element
        this.element = canvas.rect();

        // // overwrite the default this.el by pointing to the DOM object in
        // // Raphael. This works for older version of backbone.js
        // this.el = this.element.node;

        // in backbone 0.9.0+, you are not supposed to override the DOM object 
        // directly. rather, use the new setElement method which also takes 
        // care of the cached this.$el jquery object.
        this.setElement(this.element.node);

        // now that we have overwritten the default this.el DOM object, 
        // we need to rebind the events
        this.delegateEvents(this.events);
    },
    events: { 
        "click": "click" 
    }, 
    click: function(){ 
        alert('clicked');
    }, 
    render: function(){ 
        this.element.attr({ 
            x: this.model.get('xPos'),
            y: this.model.get('yPos'),
            width: 50,
            height: 50,
            fill: "#EEEEEE", 
            stroke: "none", 
            cursor: "move" 
        }); 
        return this; 
    } 
}); 

Преимущество в том, что вам нужно только отредактировать DOM в одном месте (в функции рендеринга), и вы все равно можете использовать отличную обработку событий Backbone.js. Я смог получить аналогичное решение для работы с Raphael 2.0. Хотя я немного опаздываю на вечеринку, я думал, что опубликую это, чтобы он помог кому-то еще!