Skip to content

Instantly share code, notes, and snippets.

@karlwestin
Last active August 29, 2015 14:04
Show Gist options
  • Save karlwestin/7fd7e503b3ae1b25485f to your computer and use it in GitHub Desktop.
Save karlwestin/7fd7e503b3ae1b25485f to your computer and use it in GitHub Desktop.
What i mean about angular templates

Angular templates are very cool and all, there's jsut one thing im used to that im missing:

This is only about building/packaging your JS for prod

What i do today:

When i require a handlebars template with require.js:

require(["hbs!my-template"], function(tmpl) {
  //use the template in here  
});

HBS can parse the template, find dependencies and subdependencies, and include all those. Further, with require.js i can automatically get all the dependencies included in my build, just by asking for my-template

What grunt-angular-templates and all the other angular suggestions do:

They all seem to work more or less the same way:

  1. Scan directory for all files named "*.mysuffix", for example templates/dashboard/**/*.html
  2. Concat all those and add them to template cache, when your one single angular app starts

Why can't i do like everyone else?

  1. I have more than one angular app on a page
  2. I have several different pages, where some reuses widgets from each other The angular community seems to favor folder structures like this
  app
    /directives
      /dashboard
      /settings
    /controllers
      /dashboard
      /settings
    /templates
      /dashboard
      /settings

My opinion is that that stuff only works for small apps. For larger apps you need smth like this:

  app
    /widgets
      /account
      /other-thing
    /pages
      /dashboard
      /settings

A widget can be used on both dashboard/settings, and that folder contains a controller it needs, a template it needs and so. All code concerning one unit on the page is in one folder.

@trodrigues
Copy link

Ok, so I will first explain you what we do in Contentful in regards to directory structure.

We do follow the second approach (kind of). It probably needs some cleanup but it's kinda like that.

Our structure looks kinda like this (we mostly have tabs, in the app, so assume tabs == pages):

app
  /components
    /shared
    /tabs
  /directives
  /services
  /classes

Shared and tabs contain component directories which are like what you described: one controller, one directive, one template. A tab usually has one main component and may be split into other components which are included by that main one (or it might include shared components.

The top level directives dir contains utility directives which don't really need a template or controller and just add functionality to something (example: a copy paste directive which uses ZeroClipboard).

Services are, well, services, and classes are just plain javascript classes that are mostly used by factories.

Now, regarding templates, what we do is probably a bit like what you don't want to do. We look for all the hamlcoffee files (yeah, I know, we're trying to get rid of it), concatenate them, they're all exposed on an object which then has functions for each template that get fed to each directive.

I don't see however why you can't do what you want, which seems to be more like an on demand request of templates.

The problem here is the tooling you're trying to use that assumes only one way of working. This was always a gripe of mine with a lot of tooling in the JS world, that they completely disregard layered loading of apps.

However, require.js allows you to do that, albeit with a not so straightforward configuration, and even browserify in more recent versions.

What I would suggest you do is the following:

  • compile each template file from template form to JS separately
  • wrap them as modules, and load them independently

That way you can treat them as plain modules and layer your build as you want with your build tool.

You can see an example of this here https://github.com/trodrigues/pipelined-node-app/blob/master/Makefile of something that I was trying to do for our new build process (check this post if you don't really understand what the Makefile is doing but it's exactly what I said before https://blog.jcoglan.com/2014/02/05/building-javascript-projects-with-make/)

I hope that helps :)

@karlwestin
Copy link
Author

i think its a great idea like you say, to compile each template as its own module, and then use require.js, browserify, or what have you this month to put it all together.

also, on the level "tab 'page-A' uses template 'page-A.tmpl' ", its not very complicated, there we're all good i think

What i wanna do is to have something that, when i load 'page-A.tmpl', reads that that page loads 'my-widget.tmpl' via ng-include, and load my-widget.tmpl as well

Use the angular compiler to parse out the ng-include directives in the build, so basically:
findDeps("page-A.tmpl"), and then finding subdeps in turn from that..

good discussion, the journey continues :)

@trodrigues
Copy link

I honestly think I never used ng-include and I think we don't use it internally. We just pull every template through directives (our routing is weird, Jan wrote about it here http://jan.varwig.org/archive/angularjs-views-vs-directives) so I honestly don't know what tooling exists on top of that for compiling.

However, including templates required by templates in my view should be the job of the template compiler. For instance, in Handlebars, if you use partials, it pulls the partial file by itself.

@karlwestin
Copy link
Author

including templates required by templates in my view should be the job of the template compiler.

Yeah, thats exactly my opinion too, except i haven't seen a template compiler that does it for angular :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment