Событие просмотра магистрали не срабатывает - не знаю, почему

Я пытаюсь запустить событие click, но оно не работает. Может быть, кто-то может видеть что-то, что я не могу.

ConnectionView = GlobalView.extend({
    tagName: 'div',

    events: {
        "click .social-links": "check"
    },

    initialize: function() {
        this.render();

        this.model.bind("change", this.render);
    },

    render: function() {
        // Compile the template using underscore
        var template = _.template($("#connection-template").html(), this.model.toJSON());

        // Load the compiled HTML into the Backbone "el"
        $(this.el).html(template);        
    },

    check: function(e) {
        e.preventDefault();

        alert("woot");
    }
});

Вот шаблон, который он тянет:

<script id="connection-template" type="text/template">
    <a id="link-<%= alt %>" class="social-links" href="<%= url.replace('||state||', state).replace('||timestamp||', time) %>">add <%= name %></a>
</script>

Вот представление, которое помещает ConnectionView в DOM:

ConnectionsView = GlobalView.extend({
    tagName: 'div',

    initialize: function(){
        this.collection.bind("reset", this.render, this);
    },

    render: function(){        
        var $connections = $("<div class='external-accounts'>");

        this.collection.each(function (model) {            
            var conn = new ConnectionView({model: model});
            $connections.append(conn.el);
        });

        // Compile the template using underscore
        var template = _.template($("#connections-template").html());
        // Load the compiled HTML into the Backbone "el"
        $(this.el).html(template({
            connectionsList: $connections.outer()
        }));
    },

    destroy: function() {
        this.constructor.__super__.destroy.apply(this);

    }
});

person xil3    schedule 26.06.2012    source источник
comment
Где код, который вставляет ConnectionView el в DOM?   -  person Esailija    schedule 26.06.2012
comment
Я обновил вопрос с этим.   -  person xil3    schedule 26.06.2012
comment
.outer — это пользовательский метод, который я добавил в jQuery — он просто создает оболочку <div> и извлекает из нее .html. Причина, по которой я это сделал, заключалась в том, что .html захватил только то, что было в текущем элементе, но не все.   -  person xil3    schedule 27.06.2012


Ответы (1)


Ваша проблема в том, как вы заполняете ConnectionsView el. Вы делаете это:

// Load the compiled HTML into the Backbone "el"
$(this.el).html(template({
    connectionsList: $connections.outer()
}));

Я понятия не имею, что такое .outer(), но это не имеет большого значения. Важно то, что все проходит через скомпилированную функцию Underscore template(), а это означает, что все в конечном итоге будет преобразовано в строки по пути на страницу. Как только ваши элементы DOM в $connections находятся в строке, привязки событий теряются, и больше ничего не работает.

Рассмотрим этот пример:

http://jsfiddle.net/ambiguous/4tjTm/

Там мы делаем это:

var $connections = $('<div>');
var conn = new ConnectionView({ model: m });
$connections.append(conn.el);

var template = _.template('<%= connectionsList %>');
$('#view-goes-here').append(template({
    connectionsList: $connections.html()
}));

чтобы добавить свой ConnectionView на страницу. События там не работают, потому что template() возвращает строку, и эта строка анализируется в элементы DOM, которые попадают на страницу. Но если мы добавим $connections прямо на страницу:

http://jsfiddle.net/ambiguous/AKkCJ/

используя что-то вроде этого:

var $connections = $('<div>');
var conn = new ConnectionView({ model: m });
$connections.append(conn.el);
$('#view-goes-here').append($connections);

события работают так, как ожидалось.

Итак, теперь мы знаем, что пошло не так. Но как это исправить? Все, что нам нужно сделать, это настроить ваш ConnectionsView, чтобы добавить $connections непосредственно в DOM примерно так:

render: function() {
    // Move <div class='external-accounts'> into your #connections-template.
    var template = _.template($("#connections-template").html());
    this.$el.html(template());
    var $external = this.$el.find('.external-accounts');
    this.collection.each(function (model) {
        var conn = new ConnectionView({model: model});
        $external.append(conn.el);
    });
    return this; // This is conventional
}

Вставьте <div class="external-accounts"> в шаблон ConnectionsView и вставьте ConnectionView прямо в него. Таким образом, вы всегда работаете с элементами DOM, строки не знают о событиях, но элементы DOM знают.

person mu is too short    schedule 26.06.2012