Previously this will work but I've update the underscore and backbone to the latest version, then I got error of
Uncaught TypeError: this.$el.off is not a function
http://jsfiddle.net/mmm770v8/
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
var template = _.template( $("#search_template").html(), {} );
this.el.html( template );
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function(){
// Button clicked
console.log(this.el.find('#search_input').val());
}
});
You have several problems:
Your fiddle was using jQuery 1.5.2 which is ancient and used bind/unbind instead of on/off. Backbone expects a more recent version of jQuery which has on and off functions.
You're using this.el where you mean this.$el. this.el is just a plain old DOM node, this.$el is the cached $(this.el).
The var html = _.template(tmpl, data) form of _.template went away in Underscore 1.7.0. You now need a two step process:
var t = _.template(tmpl);
var h = t(data);
so your render should look more like this:
render: function() {
var template = _.template($("#search_template").html());
this.$el.html(template({}));
}
Updated fiddle: http://jsfiddle.net/ambiguous/L5z4agh4/
Related
I created a view and has the ff codes:
var app = app || {};
app.singleFlowerView = Backbone.View.extend({
tagName: 'article',
className: 'flowerListItem',
// tells where to apply the views
template: _.template( $("#flowerElement").html() ),
// render
render: function(){
var flowerTemplate = this.template(this.model.toJSON());
// el contains all the prop above and pass to backbone
this.$el.html(flowerTemplate);
return this;
},
events: {
'mouseover': 'addBgColor',
'mouseout': 'removeBgColor'
},
addBgColor: function(){
this.$el.addBgColor('bgColorImage');
},
removeBgColor: function(){
this.$el.removeBgColor('bgColorImage');
}
});
When I run this to my HTML file I got the error addBgColor and removeBgColor is not a function. I have the CSS for this and all the models and views were set up.
Am I missing something here? Any idea why events doesn't work?
this.$el.addBgColor is the problem.
The events are triggering but you're calling addBgColor on the $el jQuery object, which is not a jQuery function, like the error message is telling you.
Check what's the difference between $el and el.
Tony, your events are cool and they are running they're just not doing anything.
this.addBgColor() will call your function in a view.
this.$el is referring to the html and there's no property called addBgColor assigned to $el.
You need to do something like change the class on your tag with the functions like so...
addBgColor: function(){
this.$el.className = 'bgColorImage'
},
.bgColorImage {
background-image: url('bgColorImage.jpg');
}
I have the following structure:
var PopupView = Backbone.View.extend({
el:'#shade',
events:{
'click .popup-cancel': 'hide',
'click .popup-commit': 'commit',
},
show: function(){
...
},
hide: function(){
...
},
initialize: function(){
_.bindAll(this, 'show','hide','commit');
}
});
var Popup1 = PopupView.extend({
render: function(){
...
},
commit: function(){
console.log('1');
...
},
});
var Popup2 = PopupView.extend({
render: function(){
...
},
commit: function(){
console.log('2');
...
},
});
The problem is that when I click .popup-commit from one of the popups, it actually triggers the methods of both of them. I've tried moving the declaration of events and initialize() up into the child classes, but that doesn't work.
What's going on, and how can I fix it (so that the commit method of only the view I'm triggering it on gets fired)?
Your problem is right here:
el:'#shade'
in your PopupView definition. That means that every single instance of PopupView or its subclasses (except of course those that provide their own el) will be bound to the same DOM node and they will all be listening to events on on id="shade" element.
You need to give each view its own el. I'd recommend against ever setting el in a view definition like that. I think you'll have a better time if you let each view create (and destroy) its own el. If you do something like:
var PopupView = Backbone.View.extend({
className: 'whatever-css-class-you-need',
tagName: 'div', // or whatever you're using to hold your popups.
attributes: { /* whatever extra attributes you need on your el */ },
//...
});
then your views will each get their own el. See the Backbone.View documentation for more information on these properties.
This is my first time create a view with Backbone, but I'm not able to render changes to an existing element in the document.
var ParamsView = Backbone.View.extend({
el: $('#node-parameters'),
initialize: function() {
console.log('WOW');
},
render: function() {
console.log('doing it');
console.log(this.$el.length);
console.log($('#node-parameters').length);
this.$el.append('<span>hello world!</span>');
return this;
}
});
var v = new ParamsView();
v->render();
The words hello world! do not appear in the target div.
The console outputs the following when the view is rendered.
WOW
doing it
0
1
So I know that my jQuery selector $('#node-parameters') is finding 1 DOM element, but the view is not use it.
Any ideas what I'm doing wrong?
EDIT: In the JS debugger I can see that this.el is undefined for the view.
Your code is probably equivalent to this :
var ParamsView = Backbone.View.extend({
el: $('#node-parameters'),
initialize: function() {
console.log('WOW');
},
render: function() {
console.log('doing it');
console.log(this.$el.length);
console.log($('#node-parameters').length);
this.$el.append('<span>hello world!</span>');
return this;
}
});
$(document).ready(function() {
var v = new ParamsView();
v.render();
});
http://jsfiddle.net/nikoshr/mNprr/
Notice that you class is declared before the DOM ready event.
You set the el at extend time with $('#node-parameters'). $ is a function that is immediately executed but, and that's why you get an undefined element, #node-parameters does not exist at that point.
By injecting the element with new ParamsView({el: '#node-parameters'}), you set a valid el after the DOM ready event. You could also set it via
var ParamsView = Backbone.View.extend({
el: '#node-parameters'
});
el is then evaluated when you instantiate your class, after the DOM ready event. http://jsfiddle.net/nikoshr/mNprr/1/
I am trying to output some h1 text on the page using backbone view but for some reason it is not working. I can show the h1 if i use it within document ready but not when I use it within the render function.
var HomeView = Backbone.View.extend({
el:'body',
intialize: function () {
this.render();
},
render: function () {
this.$el.empty();
this.$el.append("<h1>My first Backbone app</h1>"); // not showing on the page
return this;
}
})
$(document).ready(function () {
wineApp = new HomeView();
})
this.el is a DOM element while this.$el is a jQuery object. jQuery objects have an append function which is not available for plain DOM elements.
You can also convert the DOM element into a jQuery object by running $(this.el).
It's a typo: the function intialize should be called in i tialize. At the moment the function isn't invoked at all.
I am having a problem the Backbone.js View not rendering. My code is fairly simple and looks like this:
TableView = Backbone.View.extend({
initialize : function() {
this.render();
},
render : function() {
var template = _.template($("#table_template").html(), {});
alert(this.el);
this.el.html('Go');
//this.el.html(template);
},
events: {
},
});
And this is the code for instaniting the object and setting the el
<script type="text/javascript">
$(document).ready(function() {
var t = $("#table_1");
//This works!!!
t.html('Test');
//Passing the element as the el, never works
var table = new TableView({el : t});
});
</script>
Except it always says in the console:
Uncaught TypeError: Object #<HTMLDivElement> has no method 'html' .
Am I doing something wrong here? I'm using Jquery.1.7.2, backbone 0.9.2, underscore 1.3.3 and json2.
this.el is an element not a jQuery object. Try $(this.el).html() or this.$el.html()
It should be
var table = new TableView({el : "#table_1"});