Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS and Play Framework model binding and templates

I was wondering if anyone has figured out a good way to bind the model between Play Framework and AngularJS. For example you hit a URL and the page is generated by Play Framework using templates on the server-side for a given Person object. Now you want to use AngularJS to enable rich user experience and use that Person object within the JavaScript/AngularJS templates on the client-side.

One way of doing this would be to make another Ajax call from AngulraJS and populate the JS model. This seem redundent with the first call to generate the page for that Person object.

Another way would be to do something like this:

person = @Html(FrontEnd.personToJSON(thisPersonObject));

But then you need to set the person object within the $scope. Moreover this seems like a hack since the whole object is in JSON format, will be placed inside the html page.

I know there is better ways to architect this web app for example using SPA design where Play is just a service layer with a clean API for data retrieval and manipulation. This will enable you to do MVC strictly on the client-side.

Any thoughts?

like image 276
Dimitry Avatar asked Oct 03 '13 18:10

Dimitry


4 Answers

Angular was designed to be one single page application, so you should avoid trying to bootstrap the page already with data. Instead, you should provide a restful API with your framework and use angular's resources or some alternative (e.g.: restangular) to receive and send data from the server.

To sum up: Your application/site should only communicate with your framework using the an api.

like image 93
andrefarzat Avatar answered Nov 11 '22 02:11

andrefarzat


What you proposed is a viable approach with AngularJS. Another solution would be to run the javascript code on the server side, and then send the output to the browser (Similar to Airbnb's Rendr). However, nothing like this exists that I know of for AngularJS. It might not be possible because of the way the scopes are handled.

With the bootstrapped javascript object approach, it's simple and you avoid visiting the server twice.

So,

  1. Construct your app as a SPA client that consumes a REST API.
  2. Using server-side templating, render an extra javascript object with the data you want to bootstrap and include it on the page (or another js file).
  3. On the front-end, transfer the data from this bootstrapped javascript object into your $resource model.

See this similar question with AngularJS and Rails.
How to bootstrap data as it it were fetched by a $resource service in Angular.js

For SEO, use this AngularJS SEO guide [1]. This guide was mentioned by AngularJS engineers at Google I/O [2].

[1] http://www.yearofmoo.com/2012/11/angularjs-and-seo.html
[2] http://www.youtube.com/watch?feature=player_detailpage&v=HCR7i5F5L8c#t=2238

like image 39
Shridhar Gupta Avatar answered Nov 11 '22 02:11

Shridhar Gupta


For a web application I'm building we have tried using socket.io and smarty template engine when I make a call to the server I specify a smarty .tpl file that I want the server to render and then it returns the front end the finish html. I have used the requested smarty template to handle for loops and such and put in the handlebars and ng-clicks where I know I will need them, and then when the html comes back to the front end I compile it to the relevant scope and inject it in the DOM.

I found this to be a bad approach though because like the above person said Angular was meant to be a client side solution and trying to do something like this is really just muddying the water.

If you are trying to mess with figuring out a way for the backend to render angular template because you are worried about performance issues I suggest you look into building yourself a set of custom directives that will reduce the amount of watch listeners that get added to the page by binding data only once where it's needed.

like image 2
btm1 Avatar answered Nov 11 '22 03:11

btm1


Through Play, the eventual seed (https://github.com/angyjoe/eventual) retrieves a Celebrity object as a JSON. The fields of this JSON are then communicated to AngularJS models in an HTML page. Thus, you do without Play Scala templates and survive with AngularJS richness on the client-side.

like image 2
user2845946 Avatar answered Nov 11 '22 03:11

user2845946