This is a simple backbone view class that i have:
class Student.Views.SharedChat extends Backbone.Marionette.ItemView
template: 'student/shared/chat/chat'
onRender: ->
Student.CurrentUserChannel.bind('student:chat_threads:created', #setUpThread)
setUpThread: (data) ->
channel = Student.Pusher.subscribe("presence-thread-1")
channel.bind('student:chat_messages:created', #newMessage)
newMessage: (data) ->
do something with data...
end
My question is, how do i call #newMessage, from what the above code looks like, the channel binding to the #newMessage does not recognize it within that scope, how do i access newMessage function from that binding?
Appreciate your replies, this is kind of driving me against the wall.
Though i had tried the fat arrows before, but i guess i did not not totally understand it. niko's reply made me think and read about it a bit more. The problem was that the #setUpThread itself was being called as a function that was already binded, so the fat arrow needed to be for #setUpThread to maintain # and not for #newMessage.
I'd do this:
channel.bind('student:chat_messages:created', (data)=>#newMessage(data))
Related
I am on way to learning backbonejs.
I am working with the popular todo list tutorial.
I have certain questions about which i am a bit confused:
In one the models i found this function:
toggle: function() { this.save({completed: !this.get(’completed’)});}
The thing that i don't understand is this.save function. How does it work? What does it actually saves and where. And what does the code inside this function means: completed: !this.get and so on.
In one of the views i found this line of code:
this.input = this.$(’#new-todo’);
Now what does this.input means? And i also don't understand the sytnax this.$('#new-todo');
Let me know if more code is needed for comprehension. Also if anyone could point me to great learning resources for backbone, it will be awesome. Currently i am learning from 'Backbone Fundamentals' by addyosmani.
Backbone Model and Collection both have url properties.
When set properly backbone will make a HTTP POST request with the model as a payload to the url when saved for the first time (id property has not peen set). I you call save and the models id has been already set, backbone will by default make PUT request to the url. Models fetch function generates a GET request and delete a DELETE request.
This is how backbone is made to work with RESTfull JSON interfaces.
When saving a model you can define the actual model to save like it's done in the example.
Read the Backbone.js documentation. It's ok!
http://backbonejs.org/#View-dollar
this.$('#new-todo') // this.$el.find('#new-todo')
toggle: function() { this.save({completed: !this.get(’completed’)});}
Its basically saving inverse value to "completed" attribute of model. so if model's current attribute is true, it would save it to false !
regarding this.input = this.$(’#new-todo’);
Its basically saving/caching DOM with id "new-todo" from current VIEW's 'el' to view instance's 'input' property. so that we do not have to call jQuery methods for getting the same element when we need in future.
hope this helps.
:)
I too am a backbone newbie and i had been in search of good tutorials that gave good insights into the basics and i found after around 3-4 days of searching. Go through backbonetutorials.com and there is a video compiled which gives exactly what we need to know about Routers, Collections, Views and Models.
The sample working can be found at : http://backbonetutorials.com/videos/beginner/
Although this tutorial is a very basic one, you need to have basic jquery, javascript knowledge. Keep http://www.jquery.com opened in another tab as well when you go through the sample codes. Documentation is extremely useful.
Once you have good knowledge of jquery then if you go through the tutorials, you will understand and pick it up a lot better. And once you get hold of the MV* pattern of backbone you'll love it.
p.s : Do not copy paste codes or functions if you need to learn, type them.!!..
Cheers
Roy
toggle: function() { this.save({completed: !this.get(’completed’)});}
Backbone Model have a url property, when you set a property backbone makes a HTTP request to that url to save that value to the data source.
Here it is setting the value of "completed" attribute with inverse of earlier "completed" value, which will be saved to the data source
For context I use coffeescript. If I create a base model that extends Backbone.Model and I create another class (i.e. App.Models.Project extends App.Models.Base).. everything works as expected.. what would be the difference to an instance of Project if in this base class I wrote:
initialize: ->
super
console.log 'hi'
and just plain
initialize: ->
console.log 'hi'
Without spending too much time, it seems in my console an instantiated object acts as expected in both cases.. I hear you should 'always call super' here but I don't know what I'm getting..
Backbone.Model.initialize does nothing.
From the annotated source code, you can see the empty function defined in Backbone.Model
initialize: function(){}
It's upto your model to override. Usually, model variables are set here. Whenever you create a model object, initialize is called internally.
The same principle holds good when creating Views and Collections too.
Having seen it in a couple of tutorials, I'm trying to execute the following line of code in my view
#model.on('change', #render, this)
Unfortunately the change event is not firing and therefore my view is not re-rendering.
I've tried binding to different events and creating a couple of custom events using the trigger function but nothing seems to be firing at all on the model. Furthermore, there are no errors coming from the console. The change event is working fine on a different collection. I'm using Zepto 1.0, Backbone.js 0.9.2 and Underscore.js 1.3.1
EDIT: I'm trying to execute the following from the Router
place: (id) ->
#model = new GM.Models.Place({id: "#{id}"})
#model.fetch
view = new GM.Views.Place(model: #model)
$('#container').html(view.render().el)
And my model is set up like this:
class GM.Models.Place extends Backbone.Model
urlRoot: '/mobile/place'
I am wondering if anyone has experienced similar problems before and has a quick fix.
If not and you need more of the code to find an explanation please let me know...
You're not actually calling the #model.fetch method anywhere. This:
#model.fetch
is not a method call, you need to add parentheses or arguments if you want to call the method:
#model.fetch()
# or
#model.fetch success: -> ...
# etc.
Otherwise you're just producing this.model.fetch; in the JavaScript and that doesn't do anything useful.
What is the best way to bind events to a Backbone boilerplate application? I've been trying to bind my events directly to the models associated with my views, in my views, but it doesn't seem to be working. I see within 'namespace.js', that there is an app key that extends Backbone.Events like so:
// Keep active application instances namespaced under an app object.
app: _.extend({}, Backbone.Events)
I don't fully understand how to use it...
I was able to get things working without the boilerplate, but it does provide some very cool functionality, so I'd love to be able to use it. Thanks!
ADDED
the code I was using was with the underscore bind method like so:
this.module.bind('change', this.render);
But then, I realized that 'this.model' is returning undefined, and so this doesn't work. I really am not sure how the boilerplate wants me to reference my model from the view.
I'm not sure if it is a typo that you copied from your code or a typo you only entered here, but I believe this.module (which IS undefined) should be this.model, which you also must be sure to pass in when you instantiate your view, of course, as so:
myView = new BBView({model: myModel});
then you can say this.model.bind('change', this.render); or this.model.on('change', this.render); for the most recent version of Backbone
I frequently bind my views to change events on my models in this way.
As for extending Backbone.Events, the way I have used it is to create an independent "event aggregator" that will help connect events between different views on your page. Let's say for example you have some action on one view that needs to set off an action on another view. In this case, you can pass your event aggregator object as an option to each of your views when you instantiate them, so that they can both trigger events or bind to events on a common object (i.e. your event aggregator).
whatsUp = _.extend({}, Backbone.Events) // the aggregator
myFirstView = new FirstBBView ({whatsUp: whatsUp});
(the aggregator shows up as this.options.whatsUp inside the view)
mySecondView = new SecondBBView2 ({whatsUp: whatsUp});
inside FirstBBView:
this.options.whatsUp.bind('specialEvent', function(arg1,arg2) {
// do stuff
});
inside SecondBBView, when something important happens:
this.options.whatsUp.trigger('specialEvent', {arg1: 'some data', arg2: 'more data'});
For a great explanation, see this great article by Derick Bailey
Pretty new to backbone.js so forgive me of my ignorance. I'm wondering, is there a way to encapsulate functions within the View class specifically?
I ask because when setting default events...
events {
'click .something' : 'doSomething'
}
... I'd prefer to have doSomething be nested in an encapsulating object for optimal organization. For example:
ui: {
doSomething: function() {}
}
But then I can't seem to get the default events to work.
events {
'click .something' : 'ui.doSomething' // this doesn't work
}
Any help is greatly appreciated. Or, if you can tell me why I shouldn't be doing this then I'd appreciate that, as well. Thanks!
Looking through the source that binds the events (delegateEvents) which is called from the constructor, it is pretty clear that it works on variables with in the scope of the object.
http://documentcloud.github.com/backbone/docs/backbone.html#section-118
You could, however, override delegateEvents to be a bit smarter... You could parse the value for dots and chain your tokens. You could even check the type of the value and use an actual function in place of the string. That might give you better control the way you want.
More info on the delegateEvents function: http://documentcloud.github.com/backbone/#View-delegateEvents