Как обрабатывать события объектов вне представления в backbone.js?

Как и в примере с backbone-todolist, у меня есть набор элементов. Я сделал 2 представления, одно для списка и по одному для каждого элемента. Это прекрасно работает.

Однако, поскольку мне нужно, чтобы элементы списка были изменены, в представлении элемента я обрабатываю событие изменения, открывая всплывающее окно с плагин colorbox, который содержит HTML-форму. HTML создается динамически и передается в элемент colorbox.

Я использую дополнительные плагины colorbox и backbone-form.

Теперь: всплывающее окно НЕ ЯВЛЯЕТСЯ ДЕТСКИМ (в DOM) на мой взгляд, поэтому я не знаю, как запустить событие в действии «кнопка отправки».

Вот фрагмент кода (неиспользуемые части опущены):

// ** view of the single collection element
window.listElement = Backbone.View.extend({
    tagName: 'li',

    [...]

    updateElement:function(){
        //creates the update form in a popup menu
        var form=new Backbone.Form({BLA BLA BLA...I TESTED IT, IT WORKS.
            }).render();
        $(form.el).append('<input id="update-btn" type="button" name="updateBtn" value="Update" style="display: block;">');
        self=this;

        //HERE COME THE TROUBLES
        $.colorbox({
            html:form.el,
            [...] /SOME OTHER PARAMS
            }).delegate('#update-btn','click',self.saveEl());
        },
    saveEl:function(){
        console.log("now saving..")},       
        },

Что происходит, так это то, что метод saveEl (или функция? Какой термин был бы более правильным?) запускается при открытии всплывающего окна.

Я также пробовал с другой версией кода:

    initialize: function(){//added this in the initialize function
        _.bindAll(this, "saveEl");
        $('#update-btn').bind('click', this.saveEl());
          },
    updateElement:function(){
        //LIKE BEFORE BUT WITHOUT DELEGATE FUNCTION
        $.colorbox({
            html:form.el,
            [...] /SOME OTHER PARAMS
            });
        },
        saveEl:function(){
           console.log("now saving..")},        
        },

Во втором случае функция saveEl вызывается при создании представления (по одному разу для каждого элемента списка).

Я знаю, что я мог бы сделать представление для всплывающего окна, но что-то говорит мне, что это слишком сложно и что мне нужна более простая архитектура.

Вопрос, на самом деле, более общий: можно ли обрабатывать события, запускаемые DOM-объектом вне области $(this.el) без создания для них представления?

заранее спасибо.

-----------------ОБНОВЛЕНИЕ:--------------

Окончательная версия рабочего кода выглядит следующим образом:

// ** view of the single collection element
window.listElement = Backbone.View.extend({
    tagName: 'li',

    [...]

    updateElement:function(){
        //creates the update form in a popup menu
        var form=new Backbone.Form({BLA BLA BLA...I TESTED IT, IT WORKS.
            }).render();
        $(form.el).append('<input id="update-btn" type="button" name="updateBtn" value="Update" style="display: block;">');
        $(form.el).delegate('#update-btn','click',this.saveEl())
        $.colorbox({
            html:form.el,
            [...] /SOME OTHER PARAMS
            });
        },
    saveEl:function(){
        console.log("now saving..")},       
        }
     });

person Daniele B    schedule 19.01.2012    source источник
comment
первый комментарий после отладки: изменение $('#update-btn').bind('click', this.saveEl()); to $('#update-btn').bind('click', this.saveEl); (БЕЗ СКОБОК после this.saveEl) устраняет проблему вызова функции один раз для каждого представления...   -  person Daniele B    schedule 19.01.2012


Ответы (1)


ИЗМЕНИТЬ:

$.colorbox не отправляет правильный html для его привязки.

Как видите, вы передаете colorbox form.el, поэтому вы можете напрямую связать form.el:

$(form.el).on('click', '#update-btn', self.saveEl);
// here your colorbox code
$.colorbox({
    html: form.el,
    // [...] SOME OTHER PARAMS
});

Вы должны использовать on сейчас, потому что delegate – это старый метод: http://api.jquery.com/on/

----------------------

Да, вы можете обрабатывать события, запускаемые DOM-объектом вне области представления, вам просто нужно использовать $('#your-element') вместо this.$('#your-element').

Для вашего кода нормально запускать saveEl напрямую, потому что вы передаете delegate результат этой функции, вам нужно указать указатель функции следующим образом:

$.colorbox({
    html: form.el,
    // [...] SOME OTHER PARAMS
}).delegate('#update-btn', 'click', self.saveEl); // without ()
person Atinux    schedule 19.01.2012
comment
спасибо за Ваш ответ. Я имею дело с javascript несколько месяцев, поэтому мне нужно освежить многие вещи, которые я изучил в программировании на разных языках (например, указатель и функция). Тем не менее, это все еще не работает. Я использовал делегат, как вы предлагаете, но ничего не происходит, и я не могу понять, почему. Может быть, добавление его после цветовых кодов - не лучшее решение? Кроме того: сформируйте свой ответ. Я понимаю, что размещение $('#update-btn').bind('click', this.saveEl) в функции инициализации ограничивает область привязки в представлении. Не так ли? - person Daniele B; 19.01.2012
comment
Наоборот, с помощью $('#update-btn').bind('click', this.saveEl) вы не ограничиваете область действия. Метод делегирования не работает, потому что $.colorbox не отправляет обратно правильный элемент для привязки... Я отредактирую свой ответ, чтобы дать вам правильный подход, я просто нахожу решение сейчас. - person Atinux; 19.01.2012
comment
еще раз спасибо. Я попытался поставить $('#updatebtn').bind('click',this.saveRI); в инициализации представления, но это не работает: может быть, потому что элемент $('#updatebtn') все еще не существует при привязке? Единственный обходной путь, который я нашел на данный момент, - это расширить представление Backbone.Form, добавив events:{"click #updatebtn":"functionToBeTriggered"}... это означает создание представления (решение, которое я не хотел использовать)... однако я подожду вашего кода. Спасибо и до свидания. До свидания :-) - person Daniele B; 19.01.2012
comment
Дорогой Atinux, наконец-то я это сделал!! просто добавив $(form.el).delegate('#updatebtn','click', this.saveEl); после создания формы. Большое спасибо, без вашей помощи я мог бы застрять на этой простой задаче на долгое время. - person Daniele B; 19.01.2012
comment
С удовольствием ! Я отредактировал свой исходный пост и объяснил, что вам нужно использовать метод on вместо delegate (старый метод). - person Atinux; 19.01.2012
comment
Да я видел это. Спасибо, очень доходчиво и полезно. Я использовал функцию делегата (а не 'on'), так как я использую jquery‹1.7. Я поместил в разделе EDIT своего поста окончательную версию рабочего кода для пользователей, которые заинтересованы в этом. пока. - person Daniele B; 20.01.2012