I think just using Backbone.js is perfect for this type of application that you are describing. You probably already read this, but the bulk of the main literature is concentrated around your views related to the server-generated JSON models and collections, and then using the View visualization function to create (on the client) an HTML interface that represents the model / collection.
However, <is not used for this . In fact, there is nothing that would prevent you from attaching views to existing elements that already contain content that gives you all the benefits of a modular trunking system, event system, etc. I often use views that donβt have a model or collection, just because I like style matching. I also used this approach, as described below in cases where I had to work with old existing applications that have not yet received or will never have a good REST API, but they provide content in HTML.
First, suppose the following HTML is one of your widgets:
<div id="widget"> <div class="widget-title"></div> <div class="widget-body"> <a href="/Controller/DoWidgetStuff">Do something!</a> </div> </div>
In this case, you can use the trunk with one Widget model. This will be a very simple model, for example:
App.WidgetModel = Backbone.Model.extend({ intialize: function () { this.url = this.options.url; } });
Note that Widget receives the URL as a parameter to the constructor / initialization function. This widget model will represent many of your widgets (and, of course, you could take this general approach with more complex models and wrest different data from the rendered HTML). So, the next one is for your views. As you probably know, you usually transmit most views of a model or collection when you create them. However, in this case, you can create the widget model in the View initialization function and pass the URL from the pre-processed HTML as follows:
App.WidgetView = App.View.ComboboxView = Backbone.View.extend({ initialize: function () { this.model = new App.WidgetModel({}, { url: this.$("a").attr("href") }); }
Thus, the instantiation will look something like this:
new App.WidgetView({el: $("#widget")})'
By doing all of the above, you can do almost everything that the spine offers you and its modular and encapsulated is beautiful, and thatβs what you need.
The end result of this whole approach is:
- You have visualized the Widget interface as pure HTML, which (I assume) works without JavaScript.
- You are attaching a view to existing HTML.
- You go into the view as parameters, content extracted (e.g. URL) from the rendered HTML using jQuery.
- In the view, he is responsible for creating an instance of the Model with the appropriate parameters that the model needs (for example, URL).
- This means that all the content on the dynamic server side is contained within the rendered HTML, and your View is a modular JavaScript component that can do something useful for it, which, I think, is the end result that you are after.
So, you mentioned that you would like to have AJAX functionality for your widgets and this is great with this approach. Using this approach, you can now use the standard Backbone fetch and save functions in the Widget model to get new content. In this example, this is the URL obtained from the displayed HTML. When you get the answer, you can use the view, render, or other fine-grained functions to update the HTML on the page as needed.
A few points:
The only thing you need to pay attention to is that you will need to change the content type of the fetch and save functions to "text / html" if that is what the server provides. For example:
this.model.fetch({ type: "POST", contentType: "text/html" });
Finally, the model I proposed is created without content. However, if your ajax calls are a "text / html" content type, you might need to play with you so that he can properly store this content in his attribute collection. See this answer for more information.