Create model instance from non-JSON server response in Backbone.js - javascript

I have a canonical model with an associated view:
var Item = Backbone.Model.extend({
url: function() {
return "/item/123"
}
});
var ItemView = Backbone.View.extend({});
However, on the server-side, at url "/item/123", my Django application does not render JSON-formatted content, but an HTML template that is designed to be directly inserted inside the main page. How can I render the model without drastically changing how my server serves dynamic content? Is it even possible or am I misunderstanding the whole philosophy behind Backbone.js?
Just to give you a little background: I am in the process of refactoring the JS code of a Django web application by integrating Backbone.js. The app itself is not very large, but it makes heavy use of Ajax calls.

I don't think you should be loading templates in a model. The loading and rendering of templates would usually be the job of the view. Try loading the HTML directly with AJAX in the render method of your view:
var ItemView = Backbone.View.extend({
render: function(){
var that = this;
$.get('/item/123', function(html){
that.$el.html(html);
});
return this;
}
});

If you havent already, have a look at the django-app Tastypie, its the go-to solution for backend to backbone and similar apps.
Without seing the code its hard to tell how much work it would be to move it all into Tastypie vs rolling your own solutions on a per-case basis, look over the documentation.

Related

initial data loading in angularjs

When building a web app where every page depends on many data sources, what's the best way to fetch the initial bits of data? When I look at twitter, I see the tweets that are visible on page load are in the HTML source, and more tweets are loaded in using AJAX as you scroll down. But there's no convenient way to get data that's already in the DOM to be inserted into the model.
Making a request for the initial data, immediately after page load seams stupid, because you've just made a lot of roundtrips to the server to fetch css, html and javascript. Would it be a bad idea to insert the data into a javascript tag on the page, so a javascript function can add the initial data?
I'm specifically asking for angularjs, but if there's an general technique, please let me know as well.
You'll be referencing your controller anyway on page load, so you won't have to have an inline script tag.
You can either set a default model and use the attribute ng-bind on initial load, or call a function to pass back data.
It's pretty typical to fetch data on load in angularjs.
Would it be best to couple Angularjs with an HTTP Client in the backend like Zend_Http_Client or Guzzle to let the server fetch the data. Then, pass the data as json to javascript upon render.
I know Angularjs is designed for Single Page applications. That's why it makes sense that it lazy loads the data.
However, if we're going to move to the approach where we still render the page dynamically and still delegate the task of organizing the content to Angularjs. What framework will be suitable to contain the AngularJS views. Right now, project templates like angular-seed are all static..
That is, the idea is the server serves a page with the embedded json object. Then angular, takes over in the client side, Fetching additional content where needed.
So instead of just a single page of contact (e.g: index.html), we would have several pages like profiles.html, products.html. The help of the backend would be particularly helpful say you have a section which doesn't change often like your username on the top right side of the page. For me, I just think it's better to have these data preloaded in your page and not have to ask the server after the page has been loaded.
As bigblind have noticed, this seems to be the way sites like facebook, gmail, twitter does it. They contain the data embedded on page load. Then, load additional content via services afterwards.
The idea is something like below:
Webservice <---------- Backend------------> Frontend
<------------------------------------------
Backend delegates the task of querying the webservice to provide initial data in the rendered page to the client. Then client, can directly connect to webservice to fetch additional content.
Using the above setup.. What is the ideal development stack?
One way to do it is to create a directive that handles the initialization before binding happens.
For example:
app.directive('initdata', function() {
return {
restrict: 'A',
link: function($scope, element, attrs) {
if ( attrs.ngBind !== undefined)
{
$scope[attrs.ngBind] = attrs.initdata ? attrs.initdata : element.text();
}
}
};
});
This directive takes either the attribute value as initial value for the bound $scope property, or the textvalue of the element.
Example usage:
<div initdata="Foo Bar" ng-bind="test1"></div>
<div initdata ng-bind="test2">Lorem Ipsem</div>
Working example on http://jsfiddle.net/6PNG8/
There's numerous way to elaborate on this; for example parsing the initdata as json and merging it with the scope, and making it work for more complicated binds, like $root.someprop. But the basis is remarkably simple.
According to the answers on this question, a JSON object in a script tag on the page seems to be the way to go. If ayone comes up with a better idea, I'll accept your answer.

Injecting additional mvc logic into ext js app

I'm new to ext js, but went through the getting started guide and have managed to create my own app.
Now I'm building a plugin for an e-commerce system (shopware) and need to dynamically extend an app.
I've managed to add a view by monkey patching an existing controller:
//{extends file="[default]backend/article/controller/main.js"}
//{namespace name=backend/article/view/main}
//{block name="backend/article/controller/main" append}
Ext.define('Shopware.apps.Article.controller.MyApp', {
override: 'Shopware.apps.Article.controller.Main',
openMainWindow: function() {
var me = this,
mainwindow = me.callOverridden();
oldTabCreation = mainwindow.createMainTabPanel;
mainwindow.createMainTabPanel = function() {
mainTab = oldTabCreation.apply(this);
mainTab.add(
Ext.create('Ext.panel.Panel',
{
title: 'Pricify',
layout: 'card'
})
);
return mainTab;
};
return mainwindow;
}
});
//{/block}
This works. I'm not sure, if it's the preferred way, but the View gets loaded at the right place and I'm quite happy (as it costs me several hours).
But there's some way to go.
How would I inject the entire logic here?
My requirements are:
I need a controller, a view and a store/model
Preferably in an own namespace
I want to separate my classes into files.
the file must reside in the plugin folder, not in the original app folder.
I could append code to the app.js file, but as far as I know, I can't attach controllers and views, nor would I know how to autoload the files.
Is there any preferred way of doing so?
EDIT
I'm now building a simple app, that's loaded before and try to inject the controllers that are then available into the app. I'll report back, once I'm ready.
Usually I would do something like this by intercepting controller events (with Ext.ux.Application override) and adding some logic on top of that. Alternatively you could extend existing controller and replace it with your custom one in the whole app, if that's feasible. Otherwise monkey patching could be the only way to extend an existing monolithic application that wasn't written with extensibility in mind.
Also, 4.2 Beta 2 should be available shortly; it includes a whole host of MVC improvements, including something like the override mentioned above. You may want to take a look at it.

what is the best architecture to show the frontend of a pure js app?

Basically, if you have a purely JS app (that get info from socket.io, or from a server with ajax request), and you need to show this data after processing it, what technique are you using?
Currently i'm creating the elements manually with code like
var myDiv = new Element('div',{ /* options */);
And injecting it where I need making all the DOM structure. I find this hard to maintain and especially for those designers that can code html, but they can't code html from JS.
Is there any way that will improve this process? Is it better to get the html from ajax? or just make html code in a string?
I'm looking for the most optimal in terms of maintenance and resources.
What you're looking for is a "template".
You have an HTML template (some divs, etc) and you bind this with the datas you provide in JS. Then, with whatever template engine you're using, you can get the full HTML.
Here are some template engines out there:
https://github.com/flatiron/plates
http://embeddedjs.com/
And a code sample using plates:
var Plates = require('plates'); // specific to node.js, see for client-side use
var html = '<div id="test">Old Value</div>';
var data = { "test": "New Value" };
var output = Plates.bind(html, data);
console.log( output ); // '<div id="test">New Value</div>'
You can store your templates either in a single file ("templates.html") loaded through ajax, or by storing it in the HTML page (not really recommended for maintenance matters).
If you store them all in an external file, you can do something like this:
templates.html:
<!-- text/html isn't parsed by the browser so we can put anything in it -->
<script type="text/html" id="template1">
<!-- put your template in there
</script>
And you can get its content through getElementById( 'template1' ).
Easiest way for you if project is in late stage to add something like jQuery.template plugin and create templates in separate files. Then, use backend to combine those peaces in single page and on DOM Ready fire up your client side app.
If your project is in early stage use AngularJs or BackboneJS frameworks. Believe me it is worth every cent :)
I would recommend you take a look at Backbone.js.
Backbone.js gives structure to web applications by providing models
with key-value binding and custom events, collections with a rich API
of enumerable functions, views with declarative event handling, and
connects it all to your existing API over a RESTful JSON interface
I use backbone even if I am not over a RESTful interface. It's pretty easy to separate the structure from the behavior ... You can achieve the same using jQuery but it wont be as neat and clean. It's one of the MV* framework. You have:
Models containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.
Collections are ordered sets of models.
Views: The general idea is to organize your interface into logical views, backed by models, each of which can be updated independently when the model changes, without having to redraw the page
Routers provides methods for routing client-side pages, and connecting them to actions and events
It's getting attention recently. Apps that were created using Backbone include:
FourSquare
LinkedIn for Mobile
This is a great resource if you're starting to work with Backbone.
Distal Templates http://code.google.com/p/distal/ :
<table id="a">
<tr><th>OPINIONS</th></tr>
<tr data-qrepeat="m keywords"><td data-qtext="m.name"></td></tr>
</table>
Then call:
distal(document.getElementById("a"), {
keywords: [
{name:"Brilliant"}, {name:"Masterpiece"}, {name:"Witty"}
]
});
will become:
<table>
<tr><th>OPINIONS</th></tr>
<tr><td>Brilliant</td></tr>
<tr><td>Masterpiece</td></tr>
<tr><td>Witty</td></tr>
</table>
And injecting it where I need making all the DOM structure. I find this hard to maintain and especially for those designers that can code html, but they can't code html from JS.
Another option is modest. As you can see from the documentation, it obviates the need for HTML chunks in javascript. The designers can change the HTML structure without needing to look at the javascript, and javascript coders can use parameters defined by the designers to fill in the data (all in javascript).
This example is from the readme:
HTML:
<div>
<contact>
<name>Casey Jones</name>
<phone>123-456-7890</phone>
</contact>
</div>
Javascript:
var contact = {
name : "Casey Jones",
cell : "123-456-7890"
};
var out = modest.render('contact',contact);

Organizing javascript code

I am making a javascript application. Normally what I do is make different modules and get users inputs or click events in $(document).ready(); function. This works fine for small applications. But when I follow the same pattern, I mean getting click events in $(document).ready(); then it gets messy.
So how can I organize this file for a huge application?
Thanks in advance
The single-best resource I've found on this subject is Addy Osmani's creative commons book, Patterns for Large-Scale JavaScript Application Architecture. It is based in part of Nicholas Zakas' Scalable JavaScript Application Architecture, adapting it to classic design patterns and a modern workflow.
Once you reach even a modest-level of complexity, you'll benefit from working with a framework built using a variation of the MVC architecture pattern. Backbone.js is the frontrunner and is a micro-framework, meaning it does less hand-holding than others. Other popular choices are Ember.js, KnockoutJS.
Extensions and boilerplates are also built on these frameworks to handle repetitive tasks such as data/model binding and scaffolding. For Backbone, check out Backbone.Marionette from Derick Bailey and Backbone Aura, a not-quite-ready-for-production adaptation of the Osmani/Zakas architectural model built using Backbone as its... well, backbone.
Being JavaScript a scripting language, structure is one of the far most important concerns in large scale Javascript projects. It is important the parts of your application are well decoupled and 'self contained'. For an example, you may create your own UI components having its own template, logic, style, localizations, etc. in a single folder. Such self containment will let you organize your complex front end code in a manageable way.
Once you have your code organized, and self contained, there are other concerns that you need to address too.
How should these loosely coupled components interact with out tight coupling
How should I optimize these individual parts to load fast in my production env
I'm the author of BoilerplateJS reference architecture for large scale applications.
http://boilerplatejs.org
It incorporates most of the best practices discussed in Nicholas Zakas'presentation. You will find a sample implementation of a modular product suite in the code as well. Have a look, you will understand the concerns you will need to pay attention in doing a large scale application with JavaScript.
Let suppose we make cross platform application like below
Sorry for dirty content removing.
We want it cross platform so we write it with JavaScript. We want our syntax to be smart, elegant and laconic, so we use jQuery.
Our source structure will be like this
In js folder we have three folders: controller, model, view. We divide our application to three (can be many more) parts: main, menu and navbar.
For each of these parts we have ...Ctrl.jsand ...View.js. We have only one model mainModel.js (just in case).
Ctrl.js is where your handlers and where you attach them to controls. For example mainCtrl.js:
app.mainCtrl = {
model: app.mainModel,
init: function(){
$('#addButton').click(function(){
this.model.addToFavorites();
});
$('#removeButton').click(function(){
this.model.removeFromFavorites();
});
}
};
(small stars on the right of the above screenshot are actually add/remove buttons )
Controller can hold references to both view and model or only to model (as in above example).
Model.js is where we update our backend and view. For example mainModel.js:
app.mainModel = {
view: app.mainView,
all: {},
favorites: {},
init: function(){
/* for example
this.all = $.parseJSON ($.load('url'));
this.favorites = $.parseJSON ($.load('url'));
*/
this.showAll();
},
showAll: function(){
this.view.show(this.all);
},
showFavorites: function(){
this.view.show(this.favorites);
},
addToFavorites: function(item){
//add item to favorites
},
removeFromFavorites: function(item){
//remove item from favorites
}
};
View.js is where we actually updates our view (by directly manipulating DOM). Methods of view can be called by related controller and/or model. For example mainView.js:
app.mainView = {
show: function (items){
//create new element for each item
}
};
And finally we have app.js file where we initialize our app:
var app = {
init: function(){
this.mainCtrl.init();
this.menuCtrl.init();
this.navbarCtrl.init();
this.mainModel.init();
this.navbarView.init();
}
};
We have only one global variable app in our application. All views, controllers and models created inside app namespace.
And finally, finally is the order of import. You should import app.js first as it defines app variable.
<script src="vendor/js/jquery.min.js"/></script>
<script src="js/app.js"/></script>
<script src="js/controller/mainCtrl.js"></script>
<script src="js/controller/menuCtrl.js"></script>
<script src="js/controller/navbarCtrl.js"></script>
<script src="js/view/mainView.js"></script>
<script src="js/view/menuView.js"></script>
<script src="js/view/navbarView.js"></script>
<script src="js/model/mainModel.js"></script>
<script>
$(function(){
app.init();
});
</script>
</body>
</html>

Advice on creating a micro-framework in JavaScript

I'd like to know what are the steps required to create a framework on top of node.js.
I believe this can be a good way to learn, that's why I'm doing this!
I've been checking other micro-frameworks and bigger frameworks but I'm not being able to understand where to start. I'd like your advice on this.
Edit: MVC Framework like Sinatra, Merb, Rails.
For an MVC framework, the basic concepts go something like this (forgive the simplicity):
var view = 'I say, "{{first}} {{second}}".';
var model = {
first: 'hello',
second: function(){
return 'world';
}
};
for(item in model){
var regex = new RegExp('{{' + item + '}}', 'gi');
if(typeof(item) == 'function')
view = view.replace(regex, model[item]());
else
view = view.replace(regex, model[item]);
}
console.log(view);
Start as simple as possible and add small enhancements:
Store views/templates as files. This gives you a chance to play with node.js's async file I/O.
Add support for more complex models - repeating items/arrays, objects containing objects
Add support for templates inside templates
Fetch your models from an external datasource. CouchDB might be fun.
Add proper controllers - these objects should know which models go with which views and how to stitch them together
Map your Http request urls to controllers and actions - /person/55 might fetch a person with id 55 from your data repository, /person/add might bring up a UI to add a person - both use a person controller with views displayed for the appropriate action.
Take a look at mustache.js for a small template engine. Note their terminology differs from mine in examples and code. What I call a view, they call a template and what I call a model, they call a view. It's a small thing but potentially confusing.
Additional resources:
A giant list of node modules. Includes templates, database, routing, and full frameworks.
MVC with Node.js - Which modules?
Root.js : A Skeletal MVC Framework for Node.js

Categories