Backbone.js:Por que não o acionamento do evento na segunda vez?
Pergunta
Eu sou relativamente novo para javascript e espinha dorsal.Eu estou hacking em um simples iniciante nível de backbone app.Eu tenho dois pontos de vista:Casa e NewEntry.A partir de Casa, eu clique em "nova entrada" para chegar ao compor NewEntry.A partir de NewEntry, clique em "cancelar" para compor a Casa.Então, eu gostaria, para alternar entre a Casa e NewEntry clicando em "cancelar" e "nova entrada", respectivamente.
No entanto, ele não funciona.Isso é o que eu tento fazer:
- Na página Inicial, clique em "novo." NewEntry renderiza corretamente.
- No NewEntry, clique em "cancelar". Casa renderiza corretamente.
- Na página Inicial, clique em "novo." NewEntry renderiza corretamente novamente.
- No NewEntry, clique em "cancelar". A casa NÃO é processado.O método associado ao evento click NÃO disparar uma segunda vez.
Eu sou extremamente perplexo!Eu não consigo descobrir o porquê.Eu gostaria de descobrir se um evento diferente é a disparar, mas não sei como.Alguém sabe o que devo fazer?
JavaScript:
var Views = {
Home: Backbone.View.extend({
template: $('#homeview-template').template(),
initialize: function() {
this.entries = new Collections.Entries();
this.entries.on('all', this.render, this);
this.entries.fetch();
},
render: function() {
var currDate = getCurrentDate();
var innerHtml = $.tmpl(this.template, {
currDate: currDate
});
this.$el.html(innerHtml);
return this;
}
}),
NewEntry: Backbone.View.extend({
template: $('#newentryview-template').template(),
events: {
'click button#cancel-new-entry': 'cancelNewEntry',
'all': 'logEvents'
},
initialize: function() {
// currently, do nothing
},
render: function() {
var innerHtml = $.tmpl(this.template);
this.$el.html(innerHtml)
return this;
},
cancelNewEntry: function() {
console.log("test 1");
window.router.showHome();
},
logEvents: function(evnt) {
console.log("works");
console.log("event", evnt);
}
})
};
var Router = Backbone.Router.extend({
initialize: function(inputs) {
this.homeView = new Views.Home();
this.newEntryView = new Views.NewEntry();
this.el = inputs.el
},
routes: {
"": 'showHome',
"#": 'showHome',
'new': 'writeNewEntry'
},
showHome: function() {
this.el.empty();
this.navigate("");
this.el.append(this.homeView.render().el);
},
writeNewEntry: function() {
this.el.empty();
this.navigate('new');
this.el.append(this.newEntryView.render().el);
}
});
HTML:
<script id='homeview-template' type='text/template'>
<h1 class='title'>My Journal</h1>
<div id='curr-date-new-entry'>
<div id='curr-date'>${currDate}</div>
<div id='new-entry'>
<a href='#/new'>New Entry</a>
</div>
</div>
</script>
<script id='newentryview-template' type='text/template'>
<h1 class='title'>New Entry</h1>
<input id='new-entry-title' placeholder='New entry title' type='text'/>
<input id='new-entry-body' placeholder='New entry content' type='text'/>
<button id='submit-new-entry'>Submit</button>
<button id='cancel-new-entry'>Cancel</button>
</script>
Solução
Provavelmente, isso corrige o problema:
writeNewEntry: function() {
this.el.empty();
this.navigate('new');
this.el.append(this.newEntryView.render().el);
//fix: http://backbonejs.org/#View-delegateEvents
this.newEntryView.delegateEvents();
}
No entanto, se o seu não reutilizar vistas eu recomendo que você instanciar a ver diretamente sobre o método writeNewEntry em vez de inicializar, desta forma você não vai precisar chamar manualmente delegateEvents:
writeNewEntry: function() {
this.el.empty();
this.navigate('new');
this.newEntryView = new Views.NewEntry();
this.el.append(this.newEntryView.render().el);
}