In a chat component's scope, we will use the Message model to
save new messages and observe changes to the Model.
new Message.List({}) is a shortcut to perform
the findAll operation on a can.Model and
return a can.List.
...
scope: {
messages: new Message.List({}),
newMessage: ""
...
The tabs Component used can-click to listen for click events.
Since this chat application uses a <form> for sending messages, we’ll use
can-submit to specify an event handler.
There’s one more helper used in the template: can-value.
This automatically two-way binds the value of an input field to an observable
property on the scope of the component (in this case, newMessage).
When submitMessage is called, a new Message is created
with new Message(). Since can-value was declared on the input element, newMessage will
always be the current text in the input field.
The body of the message is fetched from
the Component's newMessage attribute when a user submits the form.
To save the new message to the server, call save().
submitMessage: function(scope, el, ev){
ev.preventDefault();
new Message({body: this.attr("newMessage")}).save();
this.attr("newMessage", "");
}
Finally, when a new Message is created, the messages list
must be updated.
There are two ways that messages are added: from the current user,
or from another user. In the next section, we demonstrate how to use
socket.io to update the Message model with messages
from other users in real time. Binding to the created event for all
messages allows us to create a single entry point that pushes new messages
to the scope, regardless of where those messages are from.
When the chat Component is loaded, messages are loaded from the server
using can.Model and new Message.List({}). When a new message is
submitted:
submitMessage is called via the event handler bound by the can-submit attribute
a new Message is created and saved to the server
'{Message} created' detects this change and adds the new message to messages
The template is automatically updated since messages is an observable can.List
Add real-time functionality
This example uses socket.io
to enable real-time functionality. This guide won't go
into detail on how to use socket.io, but for real-time
chat the application needs two more things.
When a message is created on another chat client, socket.io
will notify this client by triggering the message-created event,
wich will render the new message in the page by adding it to the
Message model.
var socket = io.connect(myServerUrl);
socket.on('message-created', function(message){
new Message(message).created();
});
To keep the created event from firing
twice, we modify the create function in the model.
If there was simply a return statement, Model would
create and fire a create event, which socket is already
doing. By returning a Deferred, we prevent firing of
one of these events.
In CanJS,
can.Model
adds functionality tocan.Map
to work with data on a server. It enables you to:can.Model
allows you to access data from a server easily:Using any server with a REST interface,
can.Model
enables create, read, update, and destroy functionality.Create a Chat Application
To put together a chat application, we’ll use two methods from
can.Model
to fetch the messages and create new ones:In a chat component's scope, we will use the
Message
model to save new messages and observe changes to the Model.new Message.List({})
is a shortcut to perform thefindAll
operation on acan.Model
and return acan.List
.The tabs Component used
can-click
to listen for click events. Since this chat application uses a<form>
for sending messages, we’ll usecan-submit
to specify an event handler.There’s one more helper used in the template:
can-value
. This automatically two-way binds the value of an input field to an observable property on thescope
of the component (in this case,newMessage
).When
submitMessage
is called, a newMessage
is created withnew Message()
. Sincecan-value
was declared on theinput
element,newMessage
will always be the current text in theinput
field. The body of the message is fetched from the Component'snewMessage
attribute when a user submits the form.To save the new message to the server, call
save()
.Finally, when a new
Message
is created, themessages
list must be updated.There are two ways that messages are added: from the current user, or from another user. In the next section, we demonstrate how to use socket.io to update the
Message
model with messages from other users in real time. Binding to thecreated
event for all messages allows us to create a single entry point that pushes new messages to thescope
, regardless of where those messages are from.When the chat Component is loaded, messages are loaded from the server using
can.Model
andnew Message.List({})
. When a new message is submitted:submitMessage
is called via the event handler bound by thecan-submit
attributeMessage
is created and saved to the server'{Message} created'
detects this change and adds the new message tomessages
messages
is an observablecan.List
Add real-time functionality
This example uses socket.io to enable real-time functionality. This guide won't go into detail on how to use
socket.io
, but for real-time chat the application needs two more things.When a message is created on another chat client,
socket.io
will notify this client by triggering themessage-created
event, wich will render the new message in the page by adding it to theMessage
model.To keep the
created
event from firing twice, we modify thecreate
function in the model. If there was simply areturn
statement,Model
would create and fire acreate
event, whichsocket
is already doing. By returning aDeferred
, we prevent firing of one of these events.