0
votes

I'm having an architecture difficulty with application designed in Backbone.

I've got cascaded, hierarchical views, i.e. root view has header, middle and footer views. Each of them consists of some lower level views, e.g. header view consists of tabs, preferences and login/logout views. It's just a view aggregation.

I also have a configuration model, which has several attributes, it's loaded via AJAX (standard backbone fetch). The model attributes are displayed in the interface using popups, menus etc. to enable the user to choose his settings. When the user changes a setting, possibly many parts of the app will have to re-render. The configuration model holds "state" properties (e.g. property currentPeriod is used among periods which were fetched via AJAX)

Inside views, I use listenTo(this.model, 'change:currentPeriod', this.render) to make this view re-render when anything is changed in the configuration.

I set all my default state attributes inside model::parse. The problem is that if I have 10 attributes to set (after parse is over) and probably each of them will trigger some events, many of them will be run multiple times (which is not what I want).

I was looking for a possibility to set current state attributes inside parse with the {silent:true} option - then no events would be triggered. I hope some of you already had the same problem and there exists an easy solution. Thanks in advance!

3
I'm not sure what the question is. You mention using {silent:true} when you call set, to prevent change events; isn't that what you want?freejosh
@freejosh, no. I can use x.set('xxx', value, {silent: true}). But I need the same thing inside the parse function which returned value is being set after the parse function is over. Or if there is a better solution, I'd appreciate it.ducin

3 Answers

0
votes

You can either fire all events "onSet"/"onChange" or none; in other words, you can pass silent: true, or not, but it's a binary choice. You can't say "set foo, and by the way only fire off this event, not that one".

If you want that level of control I'd recommend using silent: true and then manually triggering the events you do want.

If that doesn't work for you, I'd recommend changing how you bind your events, so that you only bind a given event once; that way it won't repeat. And if that doesn't work, you can just make your render method work even if it's run multiple times; that way the event can trigger render multiple times, but it won't hurt anything.

0
votes

During fetch the reference to options remains the same between parse and set, so you could change the value of options.silent and the changes will carry over.

See this fiddle for an example of this working.

0
votes

One way to do this would be to create a proxy (a bare Backbone.Events object) and have your views listen to it. The proxy object would listen to all on the model and simply queue up the events fired by the model (eliminating duplicative events) until the model fires an "I'm done" event (which you'd trigger at the end of parse); then the proxy would fire off all the queued events and flush the queue.