Backbone events not firing again - backbone.js

I read this one but since there was no answers and the question seems to irrelevant. I would like to ask it here again. I did exactly as the backbone documentation page instructs, but gained no results. Can someone help me point out what went wrong here?
The code as following:
App.View.Task = Backbone.View.extend({
tagName: 'li',
template: _.template($("#taskTemplate").html()),
event: {
'click #edit': 'editTask'
},
editTask: function() {
alert("test");
},
render: function() {
this.$el.html(this.template(this.model.attributes));
return this;
}
})
the index.html page looks like this:
<script id="taskTemplate" type="text/template">
<button class="edit">edit</button> <button>delete</button>
</script>

You have #taskTemplate in your JS, but newe1 in your HTML.

Ignoring my typo when specify the element ID in the view, I found that the reason for Backbone not firing the event is because I load the script before that element.

Related

Events are not fired when Backbone view rendered using jquery get [duplicate]

This question already has an answer here:
Backbone click event not firing in template View
(1 answer)
Closed 6 years ago.
I am getting the entire html code using jquery get() method and setting it on the el of backbone view.The view gets rendered perfectly but the click events i added are not firing. As i am a newbie to backbone i am not able to find the issue. Any help would be appreciated.
The currentTabID is contain the div id on which i want this html to be rendered.
view.js
var MyFirstView = Backbone.View.extend({
currentTabID:'',
initialize:function(){
this.render();
},
render: function (){
var self = this;
self.el = self.options.currentTabID;
$.get('resources/html/myBB.html', function(data) {
$(self.el).html(_.template(data));
});
return this;
},
events: {
'click .savebtnBB': 'invokeME'
},
invokeME: function (){
console.log('Fired');
}
});
Html looks something like below
myBB.html
<div id="sample_tab">
<div class="sub-main">
<form>
..
</form>
</div>
<div class="button">
<button class="savebtnBB">click me</button>
</div>
</div>
view.el is an actual dom element holding the event listeners for your view. You're replacing view's reference to that element with some number and appending the template to some other element.
Your view should act like an isolated unit as much as possible. Your code for appending it to something else should be outside the view, where you're creating it. Your code should look something like the following:
var MyFirstView = Backbone.View.extend({
initialize: function() {
var self = this;
$.get('resources/html/myBB.html', function(html) {
self.template = _.template(html);
this.render();
});
},
events: {
'click .savebtnBB': 'invokeME'
},
render: function() {
this.$el.html(this.template({ /*some data for template*/ }));
},
invokeME: function() {
console.log('Fired');
}
});
var viewInstance = new MyFirstView();
/*append to whatever you want*/
$(currentTabID).append(viewInstance.el);

Uncaught Error: Cannot read property 'replace' of undefined - Backbone.js [duplicate]

I 'm trying to develop a simple RSS app using backbone.js. I 'm using this backbone.js tutorial. I 'm getting the following error, on line 2(template), when defining the template.
Can someone also tell me why is tagName: "li" defined in the tutorial?
uncaught TypeError: Cannot call method 'replace' of undefined
backbone.js
Javscript
window.SourceListView = Backbone.View.extend({
tagName:"li",
template: _.template($('#tmpl_sourcelist').html()),
initialize:function () {
this.model.bind("change", this.render, this);
this.model.bind("destroy", this.close, this);
},
render:function (eventName) {
$(this.$el).html(this.template(this.model.toJSON()));
return this;
},
close:function () {
$(this.el).unbind();
$(this.el).remove();
}
});
HTML
<script type="text/template" id="tmpl_sourcelist">
<div id="source">
<a href='#Source/<%=id%>'<%=name%></a>
</div>
</script>
thanks
You're getting your error right here:
template: _.template($('#tmpl_sourcelist').html()),
Part of _.template's internals involves calling String#replace on the uncompiled template text on the way to producing the compiled template function. That particular error usually means that you're effectively saying this:
_.template(undefined)
That can happen if there is no #tmpl_sourcelist in the DOM when you say $('#tmpl_sourcelist').html().
There are a few simple solutions:
Adjust your <script> order so that your #tmpl_sourcelist comes before you try to load your view.
Create the compiled template function in your view's initialize instead of in the view's "class" definition:
window.SourceListView = Backbone.View.extend({
tagName:"li",
initialize:function () {
this.template = _.template($('#tmpl_sourcelist').html());
//...
As far as tagName goes, the fine manual has this to say:
el view.el
[...] this.el is created from the view's tagName, className, id and attributes properties, if specified. If not, el is an empty div.
So having this in your view:
tagName: 'li'
means that Backbone will automatically create a new <li> element as your view's el.

Backbone.js click not firing

I started helping someone on a project and one of the click button doesn't work. However, on the staging server, the same identical code for the click works. Any ideas what is causing this? I am new to backbone.js and I am not sure how the same exact code can act differently on two server. I have use code comparing tools to check all the files for differences that might cause this and havn't found anything. Please see below for my code. Thanks for the help!
View.js
Views.Pin = Backbone.View.extend({
events: {
"click .gobackback": 'changeHistory'}
changeHistory: function(e) {
Backbone.history.navigate('/', {
trigger: true
}); /* strip url definition available in actions.js */
changeTitle("Home | Wazaap");
}
};
html
<span class="gobackback">← GO BACK</span>
In HTML
Instead of
<span class="gobackback">← GO BACK</span>
Try
<script type="text/template" id="goback_template">
<span class="gobackback">← GO BACK</span>
</script>
and in view add this
render: function() {
var template = _.template($('#goback_template').html());
}

simple backbone events not firing

I'm playing around with backbone.js for the first time, but can't get the events to fire properly. Can somebody explain what I'm doing wrong?
Much appreciated!
in app.js loaded at the bottom of my html:
var Discussion = Backbone.Model.extend({
defaults: {
id: null,
title: 'New discussion'
},
urlRoot: '/api/discussion'
});
var DiscussionCollection = Backbone.Collection.extend({
model: Discussion,
url: '/api/discussion'
});
var DiscussionView = Backbone.View.extend({
events: {
'click .btnCreateDiscussion': 'create',
'keypress #discussion_title': 'create'
},
initialize: function(){
//this.$el = $("#form_discussion");
this.template = _.template( $('#discussion-template').html() );
},
render: function(){
console.log("rendering");
return this;
},
create: function(){
console.log('creating a new discussion')
}
});
var discussionView = new DiscussionView({ el: $("#form_discussion"), model: Discussion });
html:
<form action="" id="form_discussion" method="post">
<label for="discussion_title">Discussion Title</label>
<input type="text" id="discussion_title" name="discussion_title" />
<input class="btnCreateDiscussion" type="button" value="Create Discussion">
<script type="text/template" id="discussion-template">
<h1><%= title %></h1>
</script>
It seems to work fine: http://jsfiddle.net/Jbahx/. (check your backbone & underscore versions, and make sure the DOM is initialized)
About what you're doing wrong though:
model: Discussion when instantiating your view. You have to give the view an instance of a model, not a class. If you give the view a model (optional), it's generally because you want to represent the data of a particular instance.
Your render method is never called, but it's useless at the moment so that's not that big a problem.
this.template = _.template( $('#discussion-template').html() ); in the initialize method. Put this as a property of the view when extending so it'll be put in the prototype of your view (even if it seems to be a singleton here): template: _.template( $('#discussion-template').html() ),.
The problem was jQuery. The most recent 1.x release didn't work, but using the most recent 2.x release fixes the problem. It would be useful if anyone could explain why we should only use 2.x in this case?
First of all, you must call Backbone.View.prototype.initialize in your overriden method to let Backbone initialize event listeners:
initialize: function(){
//this.$el = $("#form_discussion");
this.template = _.template( $('#discussion-template').html() );
Backbone.View.prototype.initialize.call(this)
},
Second, render view in initialize - it isn't best practice. Use for this separate render method.

Rendering problem

From the backbone documentation:
All views have a DOM element at all times (the el property), whether they've already been inserted into the page or not.
I have following very simple javascript file:
CBBItem = Backbone.Model.extend(
{
});
CBBTrackItem = Backbone.View.extend(
{
template: _.template("<span><%= title %></span>"),
initialize: function()
{
_.bindAll(this, "render");
},
render: function()
{
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
And a html page like this:
<script type="text/javascript">
$(function()
{
var itm1 = new CBBItem({ title: 'track 1'});
var itmUI1 = new CBBTrackItem({ model: itm1, id: "kzl" });
itmUI1.render();
});
</script>
<body>
<div id="kzl"></div>
</body>
My view item doesn't want to render although there is a created div on the page. I can trick the situation in many ways. For example doing something like this
var itm1 = new CBBItem({ title: 'track 1'});
var itmUI1 = new CBBTrackItem({ model: itm1, id: "big_kzl" });
$(itmUI1.render().el).appendTo("#kzl");
But, why is the main case not working?
Here's one possibility: you aren't setting the el for the view, so it doesn't know what to do with your template. Could you modify your view-calling code to look like this?
var itmUI1 = new CBBTrackItem({
model: itm1,
id: "big_kz1",
el: "#kz1"
});
itmUT1.render();
Alternatively, you could set the el value within the initialize of the view if the value never varies. The advantage to doing so is that callers of the view don't have to know this information and thus the view is more self-contained.
If the document already has the element you want to use as el for a particular view, you have to manually set that dom element as the el attribute when the view is initialized. Backbone provides you no shortcut for doing that.
I've experienced problems when passing values like ID and events in during construction as opposed to defining them during extension. You may want to check and see if that's the difference you're looking for.

Resources