Click here to Skip to main content
15,890,670 members
Articles / Programming Languages / Javascript
Tip/Trick

angularjs and requirejs... so easy !

Rate me:
Please Sign up or sign in to vote.
3.67/5 (4 votes)
8 Mar 2016CPOL4 min read 13.9K   5   4
getting to play angularjs and requirejs to play nicely together... piece of cake !

Introduction

I'm studying angularjs to replace my old knockoutjs app (why ? because I want to stay hip and cool like the rest of you !), and one of the first requirements for me was that angularjs would play nice with requirejs. Turns out it's a piece of cake.

Dependency injection

First, let me tell you that both angularjs and requirejs claim to do dependency injection (DI). And they're both right. But angularjs does this at a functional level, while requirejs' realm is file loading.

In short : you need the DI of angularjs to tell it where to inject templates, use controllers and services etc. But without requirejs, you need to include all your .js files in the top-level index.html page in separate <script> tags, so the browser can load them. That's hard to maintain in any non-trivial application.

With requirejs, you need only one single <script> tag in your index.html, and requirejs does the rest ! For further information about requirejs, please refer to their website.

Here's how you do it

index.html

HTML
<!DOCTYPE html>
<html >
<head>
    <meta name="viewport" content="width=device-width" />
    <title>My Amazing App</title>
    <link rel="stylesheet" type="text/css" href="Content/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="Content/ypatm.css" />
    <script type="text/javascript" data-main="scripts/app/main" src="scripts/require.js"></script>
</head>
<body>

As you can see, there are still a couple of lines for loading the css, but that's allright. Main thing is that I only need 1 <script> tag to load ALL the .js files !
In this tag, I specify 2 things :
 

  • src="scripts/require.js" : this is to tell the browser where to find require.js
  • data-main="scripts/app/main" : this is to tell requirejs where to find it's configuration and starting point (notice that the file is called "main.js", but we don't need to add the .js extension)

main.js

This is the file specified above. It contains the configuration and starting point of requirejs.

JavaScript
requirejs.config({
    baseUrl : "scripts/app",  
    paths: {
        jquery : '../jquery-1.9.1.min',
        angular: '../angular.min'
    },
    shim: {
        'angular': {
            deps:['jquery'],
            exports: 'window.angular'
        }
    }
});

// Start the main app logic.
requirejs(['angular','ypatm'], function (angular, ypatm) {

    angular.bootstrap(document, ['ypatm']);

});

There are a couple of things to notice here. Let's start with the configuration part (the top half of the code above).

Angularsjs 1.x is not AMD

In the configuration you might notice 2 things. First is that apparently, angularjs seems to depend on jquery. That's not exactly true, but since I use bootstrap in my project, and bootstrap *is* dependent on jquery, I reacon it would be a good idea to let them depend on the same version.
Secondly, angularjs is not conform to AMD (Asynchrous Module Definition), meaning it is not wired to work with requirejs. Luckily requirejs has a solution for that using a "shim" configuration as you can see above. (I think angularjs 2.x *does* conform to AMD, but I'm not sure. In that case, you would only need the "paths" bit, and leave out the "shim" part).


Simple, isn't it ?

Now let's have a look at the startup function, "requirejs".
In this function, we "instantiate" the 2 top js-files we need for our application : angular and my own application, which has the anagram "ypatm" (don't bother to find out what it means !).
 

Use angular.bootstrap, not the attribute "ng-app"

That was the hardest part for me to figure out. Every angularjs application has the directive "ng-app" as an attribute to it's very first <html> tag ! Not so when you use requirejs. The reason is simple : the directive "ng-app" has no meaning before angularjs is loaded, and angularjs is loaded only after requirejs is loaded.

So, saying to the browser : "use this directive" of a library that is not even loaded makes little sense. Fortunately (and I guess there is a bit of luck involved), angularjs offers an alternative to the "ng-app" directive, and this is to call the "bootstrap" function. That ties angularjs to the document.

And that's it ! Nothing else to do than to write that killer app of yours !

But just to see how the DI of angularjs and requirejs differ, let's have a look at my main app file, so eloquently called "yatpm.js".

ypatm.js

JavaScript
define(['angular', 'configuration', 'deploy', 'message'], function(angular, configuration, deploy, message) {
    var app = angular.module('ypatm', ['message', 'configuration', 'deploy']);

    app.filter("sanitize", ['$sce', function ($sce) {
        return function (htmlCode) {
            return $sce.trustAsHtml(htmlCode);
        }
    }]);

    app.controller("PanelController", function() {

        var tab = 1;

        return {
            selectTab: function(setTab) {
                tab = setTab;
            },
            isSelected: function (checkTab) {
                return tab === checkTab;
            }
        };
    });
});

The first line is the requirejs injection. It tells requirejs what files it need to "instantiate" (when it hasn't done so already) : "angular.js", "configuration.js", "deploy.js" and "message.js".

The second line is the angularjs injection. It tells angularjs there's a new module called "ypatm", that depends on the angularjs modules "message", "configuration" and "deploy". If the requirejs DI wouldn't be active, angularjs would not find the files in the first place, let alone the controller that they contain. (or you had to put them all in <script> tags in the index.html, which was kind of the whole point to avoid !)

So, angularjs and requirejs play very nicely together, don't you think ?

History

version 0.1.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Belgium Belgium
I'm a self-made developer. And after years of writing code, I think I don't suck at everything ! When I stumble on a problem, I can't help but to figure it out. In some cases, I even write an article about it !
Also, in my quest to write better code, I have obtained a certificate as UML Professional, and I'm also a Certified ScrumMaster.

Comments and Discussions

 
QuestionSeparate files Pin
Dmitry A. Efimenko15-Mar-16 8:14
Dmitry A. Efimenko15-Mar-16 8:14 
AnswerRe: Separate files Pin
Erwin@Attentia17-Mar-16 3:19
Erwin@Attentia17-Mar-16 3:19 
GeneralRe: Separate files Pin
Dmitry A. Efimenko17-Mar-16 9:40
Dmitry A. Efimenko17-Mar-16 9:40 
GeneralRe: Separate files Pin
Erwin@Attentia17-Mar-16 23:29
Erwin@Attentia17-Mar-16 23:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.