Backbone view събитие не се задейства - не знам защо

Опитвам се да накарам събитието 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="/bg<%= 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
Къде е кодът, който вмъква el на ConnectionView в 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