/grails-angular-template

using angular to load snippets or full html content

Primary LanguageGroovy

Grails Angular Template

Grails Angular Template is born to simplify the use of templates on a grails application using angular structures.

Dependencies

  • angularJS (We do not provide the base code.)
  • Jquery (To use the fancy css selector inside the service that we provide to you)

But how it works ?

Maybe you heard about the *Resource.groovy class before, and all that awesome dependencies structure that it provides.This plugin works together with the layoutResources. I mean behind the stuffs you will use a taglib to bootstrap some stuffs. All you're need to do is put <gat:bootstrap/> on your main.gsp or whichever layout you want to use. Following a simple example of code structure inside a ApplicationResource.groovy

modules={
	angular{
		resource url: "js/angular.js"
	}

	myAngularApp{
		dependsOn "angular"
		resource url: "js/myAngularApp.js"
	}
}

after that you can call on the head of you gsp

<head>
	<r:require module="myAngularApp"/>
</head>

voilá the angular.js and myAngularApp.js is loaded on the page in the right order. awesome right ?

The plugin was approved, and all you need to do is add compile ":grails-angular-template:0.1" on BuildConfig.groovy dependency and the plugin will be available on your project

Do you Remember the *Resources.groovy ? ok, open it. and just add grails angular template on dependsOn declaration like below

	//alot of code over 
	myAngularApp {
		dependsOn 'jquery, angular, grails-angular-template'
		resource url:'js/myAngularApp.js'
	}

Like we know when you define a module on angularJS you can inject other modules, A smart way to reuse code. so here is the code inside myAngularApp.js

var myAngularModule = angular.module('myApp', ['grails-angular-template']); 
// just that an all the code inside the grails-angular-template
// module is available to your module in that case 'myApp'

//let's define a controller  
function myController($scope, templateService){
	templateService.load('/user/template1').into('section.someSection').withData({txt: "some reasonable data here"}).start();
	templateService.load('/user/template2').into('nav.someNav').start();
}

The magic is all in the template service, when you inject the grails-angular-template module inside your module, this service is provided. another nice thing is, you can concatenate the methods. The load() and into() is required, because what do you want load and where ? but the withData() is optional.One last thing the start() must be the last method to be called.

Be Aware

withData() waits for a Map. and that map has some special keys like 'scope' and 'broadcast'

What this Scope does ?

Imagine, you will just load a piece of html that hasn't has a ng-controller defined. But in this snipped of code you use the variables of a scope working, so you just need to pass that scope in the withData({scope:$scope}) and the templateService will understand that they should use that scope to compile that snipped of template. Following a simple example

template1.gsp

<ul ng-repeat="user in users">
	<li>{{user.name}}</li>
</ul>

myAngularApp.js

function myController($scope, templateService){
	var users = [{name:"bruno"}, {name:"fabio"}, {name:"max"}];
	templateService
		.load("/user/template1")
		.into("section.listOfUsers")
		.withData({scope:$scope}).start();
}

We said to templateService loads the template1 inside a section with class listOfUsers. On the 'withData' I said to templateService to use the controller scope, with it they will iterate correctly inside the list of users that I had define early.

What this Broadcast does ?

By default after complete all cycle on the template service, they will broadcast a event, with the same name informed on load(). The data passed through that event is the map passed on withData(). If you for some reason want to listen that event and do something that is the way. If you don't want to broadcast just do withData({broadcast:false})

Methods and Arguments

  • load() @String example : '/user/templateName'
  • into() @String example : tag.someClassName or any css selector
  • withData() @Object exaple : {key:value} but with 2 special keys scope and broadcast.
  • start() @None. Make the magic happens
  • clean() _@None. Just clean the template

Changelog

  • v0.1 - templateService ready to use.
  • v0.1.1 - Release of Bug-Fix to solve the uncontrolled grow up number of scopes created. adding the cleanService.
  • v0.1.2 - Release of feature to clean the template zone. adding the 'clean' method