Backbone.View "el" confusão

97

Como uma visualização deve elser tratada? Tem que ser definido, caso contrário, os eventos não disparam (veja aqui ).

Mas deveria ser um elemento que já está na página? No meu aplicativo, eu renderizo um modelo (modelos jQuery) em um Fancybox. Qual deve elser nesse caso?

Manuel Meurer
fonte
11
Eu pensei - eu sou o único mexendo na elcoisa.
Yugal Jindle
elé como gf. ninguém pode entendê-los totalmente.
Mahi

Respostas:

121

Uma visão el é onde ocorre toda a associação de eventos. Você não precisa usá-lo, mas se quiser que o backbone dispare eventos, você precisa fazer seu trabalho de renderização no el. A views el é um elemento DOM, mas não precisa ser um elemento pré-existente. Ele será criado se você não puxar um da página atual, mas você terá que inseri-lo na página se quiser que ele faça alguma coisa.

Um exemplo: tenho uma visão que cria itens individuais

window.ItemView = Backbone.View.extend({
    tagName: "li", //this defaults to div if you don't declare it.
    template: _.template("<p><%= someModelKey %></p>"),
    events: {
         //this event will be attached to the model elements in
         //the el of every view inserted by AppView below
        "click": "someFunctionThatDoesSomething"
    },
    initialize: function () { 
        _.bindAll(this, "render");
        this.render();
    },
    render: function () {
        this.el.innerHTML = this.template(this.model.toJSON());
        return this;
    }
});
window.AppView = Backbone.View.extend({
    el: $("#someElementID"), //Here we actually grab a pre-existing element
    initialize: function () { 
        _.bindAll(this, "render");
        this.render(new myModel());
    },
    render: function (item) { 
        var view = new ItemView({ model: item });
        this.el.append(view.render().el);
    }
});

A primeira visualização apenas cria os itens da lista e a segunda visualização realmente os coloca na página. Acho que é muito semelhante ao que acontece no exemplo ToDo no site backbone.js. Acho que a convenção é renderizar o conteúdo ao el. Portanto, o el serve como um local de pouso ou um contêiner para colocar seu conteúdo modelo. O backbone então vincula seus eventos aos dados do modelo dentro dele.

Quando você cria uma vista que você pode manipular o el de quatro maneiras usando el:, tagName:, className:, e id:. Se nenhum desses for declarado, o padrão será um div sem id ou classe. Também não está associado à página neste momento. Você pode alterar a tag para outra coisa usando tagName (por exemplo tagName: "li", fornecerá um el de <li></li>). Você pode definir o id e a classe de el da mesma forma. Ainda assim, el não faz parte da sua página. A propriedade el permite que você faça uma manipulação de granulação muito fina do objeto el. Na maioria das vezes eu uso umel: $("someElementInThePage")que, na verdade, liga toda a manipulação que você faz ao el em sua visualização à página atual. Caso contrário, se você quiser ver todo o trabalho árduo que você fez em sua visualização mostrado na página, você precisará inseri-lo / anexá-lo à página em algum outro lugar de sua visualização (provavelmente no processamento). Gosto de pensar em el como o contêiner que todas as suas visualizações manipulam.

LeRoy
fonte
Obrigado pelo esclarecimento e pelo exemplo! Acho que nem sempre está claro o que el deveria ser em certas situações e o desenvolvedor precisa ter uma "sensação" dele. Suas explicações certamente ajudaram! Uma pergunta, porém: você não define um el em seu ItemView, mas o acessa na função de renderização. Isso vai funcionar? Existe algum tipo de el padrão se você não o definir explicitamente?
Manuel Meurer
3
Por padrão, el é uma tag "div" sem id ou classe. É um objeto DOM não vinculado ao DOM da sua página. Normalmente, eu o insiro / acrescento à página na função de renderização ou na função de renderização de uma visualização pai.
LeRoy
Atualizei minha resposta com alguma descrição das propriedades que definem o el.
LeRoy
5
Acho que meu único problema em obter um elemento pré-existente com el: $ ("# someElementID") é que sua visualização provavelmente sabe mais do que deveria, tornando difícil reutilizá-lo. consulte "Desacoplar a visualização do DOM ..." coenraets.org/blog/2012/01/…
Scott Coates
@scoarescoare, uma vez que você está adicionando a propriedade el na instanciação, a visão em si não sabe mais do que deveria, ela permanece modular e capaz de aceitar qualquer $ (el) que você queira entregar. Isso o torna bastante reutilizável, na verdade.
Metagrapher
6

Um pouco velho agora, mas eu também estava confuso, e para outras pessoas que chegam aqui, este violino pode ajudar - http://jsfiddle.net/hRndn/2/

var MyView = Backbone.View.extend({

    events: {
        "click .btn" : "sayHello",
    },

    sayHello : function() {
        alert("Hello");
    },


    render : function() {
        this.$el.html("<input type='button' class='btn' value='Say Hello'></input>");

    }
});

$(function() {
    myView = new MyView({el:"#parent_id"});
    myView.render();
});
Marca
fonte
Eu segui esse modelo e gostaria de não ter seguido. Para destruir uma visão e remover as ligações, a convenção do backbone é view.remove (). Isso destrói $ el e o remove do DOM, então quando você precisar mostrar a visão novamente, $ el não existe.
JJ de
@Marcar e se eu estiver usando arquitetura composta como marionete ... eu ainda preciso ter o el do view?
afr0
seu código de violino não funciona, pois o link deveria ser jsfiddle.net/hRndn
Izzy
@Mahi Sim, você está certo. Provavelmente colei o link errado, desculpe. Este funciona: jsfiddle.net/hRndn/127
Izzy
1

Você deseja que seu 'el' faça referência a um elemento que contém um elemento filho que possui qualquer evento que acione uma mudança em sua visualização. Pode ser tão largo quanto uma tag "body".

Joshvermaire
fonte
Hmm, isso também não esclarece tudo. Na maioria das vezes, os elementos que podem desencadear uma mudança em minha visualização estão dentro do modelo que a visualização renderiza, portanto, antes de ser renderizado, esses elementos ainda não existem.
Manuel Meurer