3

I've seen a bunch of posts recommending using a directory per feature with angular. Today I've added RequireJS (AMD) to a new angular application I'm working on. I was using script tags at the end of the body tag, then I did some AMD restructuring and everything magically became 300% better.

It was all going great, the AMD style require supported relative paths when working with JS files, but with templateUrl, it starts at the root instead of in the directory I'm in. I've seen solutions like reading the "currently executing script file", I doubt that approach would work with AMD.

Is there a trick I don't know about to pass the path from somewhere? I don't mind doing some work per file, but I really don't want to do something like templateUrl: baseUrl + 'template.view1.html' everywhere I use templateUrl.

I'm using ui-router, if it matters (first day, yay).

3 Answers 3

1

What about using require.toUrl(...)

Take a look to the official docs: http://requirejs.org/docs/api.html#modulenotes-urls

Sign up to request clarification or add additional context in comments.

Comments

0

I am using something like this

angular.module('...', ['...'])
    .constant('basePath', 'app/path/to/something/')

and later

templateUrl: basePath + 'morePath/myFile.html',

2 Comments

The good thing is, that you can use dependency injection. That is not visible in my three line sample but for the interested reader: stackoverflow.com/questions/17383611/… - and one side note: Of course it is also possible to use a factory and get a perhaps more dynamic value out of this. For me, the constant way worked smoothly.
I would have to remember to glue the base path to the relative path every time I use templateUrl and pass the path individually for each feature directory because I chose feature-oriented directory structure. I was hoping for something cleaner.
0

I have a little project, angular-require-lazy trying to mix RequireJS and Angular. In it I have written the templateCache AMD plugin, working as:

require(['templateCache!./navbar.html',...], function(navbarTemplate, ...) {...});

So, the proper template is loaded (using RequireJS's text! plugin under the hoods - so it is compilable with r.js too). The object you get (the navbarTemplate argument in the example above) has 2 properties, one is the actual loaded text and one the URL, under which the text is registered with Angular's templateCache. You can then use it as:

require(['templateCache!./navbar.html',...], function(navbarTemplate, ...) {
    ...
    // will give you the correct URL, with `./` expanded properly
    // the text is already registered with Angular
    templateUrl: navbarTemplate.path
    ...
});

Unfortunately, I haven't gotten into making angular-require-lazy compatible with ui-router yet, so you cannot use it as is. The code of the plugin (really small) might give you some idea for your own implementation of this feature:

define(["module", "./currentModule"], function(module, currentModule) {
    "use strict";

    /** RequireJS module loader entry point. */
    function load(name, parentRequire, onload, config) {
        parentRequire(["text!" + name], function(t) {
            if( !config || !config.isBuild ) {
                currentModule.run(["$templateCache", function($templateCache) {
                    $templateCache.put(name, t);
                }]);
            }
            onload({
                text: t,
                path: name
            });
        });
    }

    return {
        load: load
    };
});

(The currentModule is angular-require-lazy - specific, you will have to replace at least that with the current Angular module.)

2 Comments

this is a good method but I was really hoping to avoid polluting the top of the file with all these requires for templates. I realize now I can just make it work with relative paths with the text! plugin (I didn't know about it until now, I just started using r.js)
Yes, revisiting your case it may be enough to require the text!./file.html and then use it as template: file.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.