I am connected to a web socket and constantly updating my model based on the incoming JSON objects.
Using this coffeesScript code:
#listenTo #model, 'change', #render
I am listening for every moment that the model is updated and then I render that newly updated model. This works well. However, I would now like to set a timeout so that if the listener doesn't detect a model update after 30 seconds, I can call a different function and update my model with a timeout message. What is the best way set up this timeout?
I think you should add callbacks at where you send ajax requests. When you listen to a model's change event, you don't know when the request is sent.
What if you want to add features like auto-refresh? In that scenario 'change' event is listened once but there could be multiple requests that can timeout. These are separated things.
Related
Hi I have question regarding refetching of the model on backbone
is there a way to fetch all model in a model
basically if i have my model and if that said model has an attribute of model as well i could trigger a re fetch and all the model inside that model will be re fetched
my current process is i would loop all through the attribute of a model and look for a model if i could find any i would fetch it. do you have a better way to do things? any suggestions?
This is my current code
_.each(self._getModels(entityRecordModel.attributes), function (model)
{
model.fetch();
});
The pub/sub pattern can help you here.
When you first initialised the attribute models, just subscribe to the main model's sync event and then fetch them as well.
If you want to to all this in one request, then use model's parse method to initialise/reset the attribute models.
I have a SPA app that's a blogging app of sorts. You post, and then the 'feed' composite view puts the post on top.
What I envision:
1. have a sync listenTo on the post collection that, on the collection fetch(), loads all the posts.
2. have an add listenTo on the collection that will render a new post when it's added.
The problem is that on fetch(), I'm getting both add and sync events which causes duplicate posts.
What do you all suggest I do?
Thanks!
When you call fetch() for the first time on an empty collection, the collection will fire an add event for all new models, so listening for that should be enough.
When you call fetch() when the collection already has models, you will only get an add event for new models.
I have a task - to implement notifications/alerts on react+flux. Imagine the next situation user clicks on the button. After that I'm firing an action - for example "CALCULATE_ACTION" then I catch it in the MainStore. While processing this action in the MainStore I need to show the notification for user. Let's imagine I'm calculating something in the MainStore. Before the calculation I need to show notification "calculation has started". And after the calculation show "calculation has finished". I have a NotificationComponent which takes the notification text from the NotificationStore. So to show the notification I can trigger the "SHOW_NOTIFICATION_ACTION" and pass the text of the notification to this action, so the NotificationStore will catch it and set it to its state and NotificationComponent will be rerendered and notification will appear.
The problem is that I can't fire an action while other is in process. So if I've already fired "CALCULATE_ACTION" I can't fire "SHOW_NOTIFICATION_ACTION". Of course I can catch the CALCULATE_ACTION in the NotificationStore. But then I will be able to show only one notification - If I'll wait for the MainStore then notification will be after the calculations in the MainStore, otherwise - before.
And one more question- what if I need to show notification in the middle of the calculation?
My task is a bit abstract and I have more realistic one, but a lot of context should be explained so I've simplified the task to this example.
Does anybody has any ideas?
Any help would be highly appreciated!
In a typical react-flux setup, your components listen to changes in your stores.
Your component fires an action, your stores update, and your stores emit a change. (Stores should not fire actions)
In your (abstract) case, you could set it up as follows (with 1 action resulting in 2 store changes and 2 updates):
Front-end component listens to changes from BOTH NotificationStore as
well as MainStore.
This component fires a CALCULATE_ACTION.
NotificationStore listens to CALCULATE_ACTION. It immediately emits a
change. (without waiting for MainStore).
Front-end component receives this change event, and it retrieves some active_state
from NotificationStore (which in turn should probably read from
MainStore to determine active_state). You can have your component show this calculation busy' message.
Meanwhile, MainStore also received the
CALCULATE_ACTION. It starts the calculation, and as soon as it is
done, have it emit a change. Your component listens to this change
also, and will again retrieve the active_state from the
NotificationStore. Which is now abviously 'done' or something
similar.
When does the 'add' event gets fired in a collection?
I am in a notion that when i execute something like app.mycollection.create(this.newAttributes()); the add event will be fired.
Actually i do this while initializing a view
window.app.mycollection.on('add',this.render,this)
So ideally, first there should be a post request (when i do a create) and then the get request (my render function fetches rows from backend). But in network console, i get the opposite. I first see a get request and then the post request.
This made me thought that 'add' event gets fired immediately after a call to create method without waiting for creation to be complete.
This thus fetches me old data without including the data that has just been created.
Please shed some light.
You have executed render function immediately. Try update your code:
window.app.mycollection.on('add', this.render, this)
EDIT
Take a look
Creating a model will cause an immediate "add" event to be triggered
on the collection, a "request" event as the new model is sent to the
server, as well as a "sync" event, once the server has responded with
the successful creation of the model. Pass {wait: true} if you'd like
to wait for the server before adding the new model to the collection.
What is the purpose of the "success" callback when fetching data for a model vs. the purpose of binding to a method for the "change" event?
"success" callback
this.model.fetch({
url: '...'.
success: function(response) {
...
}
});
vs. model "change" binding
this.model.bind("change", this.attributesChanged);
Usually i use fetch-success callback in cases when i call fetch outside of the model itself and want an additional success function callback triggered in the model.
Also on a note, be careful with CRUD events though, as "change" events may still be trigger even when its unsuccessful in storing to the server, remember "change" is triggered when the model is changed. As of version 0.9.0, a "sync" event has been added to address this issue. This triggers whenever a model's state has been successfully synced with the server.
The main reason to use "success" or "error" for that matter, is to execute functionality based upon the response as "change" will only fire on successful change of the model. If your fetch failed for some reason, "change" won't fire. The callbacks allow you a bit finer level of control. That said, it kind of boils down to personal preference as to when you want to respond to the response. My thought is that if I am only interested in doing something in response to a successful CRUD operation, then listening for "change" is entirely appropriate, as I will just ignore errors.
The 'change' event will fire if the model is updated by any method, for example user input into a form which is used to change a model attribute, or fetching data from the server.
The success callback on fetch is obviously called only after fetching from the server.
So if you only want to respond to changes to the model caused by fetches, rather than 'bidirectional' changes, use a success handler rather than a change event.