Backbone.js with non RESTful app? (is Backbone.js right for my current project?)
I'm trying to figure out if Backbone.js is the right framework for my current project: a visualization app.
I have a number of questions:
1) State / Routing?
As this is not your typical RESTful app, but rather a visualization application with various chart types and settings for these charts, how do i maintain state in the URL? Let's say my areaChart model has a number of defaults like this:
AreaChartModel = Backbone.Model.extend({
defaults: {
selectedCountries: [],
year: 1970,
stacked: false
},
initialize: function(){
[...]
}
});
On an update to the model I'd like to serialize some of these attributes so that I can bookmark the specific state: chartApp.html#!year=1970&stacked=false etc.
And vice-versa, when initing the app with this state, how do I "deparam" the url state and set the model? Can I use Backbone's intrinsic routing?
2) Controller and coupling?
It seems as Backbone has a pretty tight view-model coupling? Is this really how I should bind for example my areaChartView to the model?
AreaChartView = Backbone.View.extend({
initialize: function(){
areaChartModel.bind("开发者_运维百科change:year", this.render);
}
});
Isn't this normally the role of the controller?
3) Continuation: Model vs. Controller?
Given this scenario:
A change in the "Sidebar" should trigger a sequence of functions:
1) "New data for the current selection should be loaded" 2) "Based on this data, the scales in the Visualization view should be updated" 3) "The visualization view should be rendered"Where should I place these functions and how can I create an event in the model that I trigger when the state is stable? (i.e. when all the functions have been invoked and it's time to set the view states?)
1) I would use Backbone.js native routing as much as possible using “:params” and “*splats” , read more. You could fit all your queries into the Backbone.js routing but I would personally sacrifice certain things in favor of intuitive UI buttons
e.g. I would have the default as a line bar and you can't preset this with the URL but to change to a stacked graph would be a simple click of a button.
I would probably stray from ever using ? and & in my URL's. I might come back to this point later as it is interesting.
2) Your example is fine and you just need to remember Backbone.js MVC terminology doesn't correlate to traditional MVC.
Backbone Views are essentially the Controller in traditional MVC. Backbone Controllers are simply a way of routing inside a framework. The templating engine you use with Backbone.js is the traditional MVC view.
3) Still writing
Regarding question #3, I would create a Model
and a View
for the slider.
Then I would associate the triggering of the change
event on the model to some function in the view that updates the graph's view (like changing the scales). Something like:
var Slider = Backbone.Model.extend({})
var SliderView = Backbone.View.extend({
initialize: function() {
this.model.bind('change', this.render);
}
render: function() {
// load data, change scales, etc.
}
});
var slider = new Slider();
var slider_view = new SliderView({ model: slider });
Maybe a good idea would be to put the bindings in a parent view, that would then dispatch to sub-views, coordinating their work.
Do sit down for a while and consider if maintaining the entire state is at all a good idea ? The key motivations for having url-based state management is being able to support browser based navigation buttons and being able to bookmark a page. In a visualization app, your data would probably change every moment. This is not something you want to persist in your app-url. Do you really want that when a user bookmarks your app and comes back to it three days later - he sees the visualization for three days old data ? For your scenario, assuming I have not misunderstood your requirements, I would recommend to keep the data state in your model itself.
Also regarding synchronization of views with model data, Yes you can code all the binding logic on your own. In that case your View class will take care of setting up the bindings on the first render. And upon subsequent calls to render, which can be invoked in response to any change event in the model, will refresh the DOM/canvas where the visualization is present.
Probably you should be look forward to a plugin for data-synchronization that takes care of much of boilerplate for you. This page lists some of the data-binding extensions available. Orchestrator is another solution that I have been working on, which might be helpful in this regard.
精彩评论