Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use RequireJS to load and run modules only once

I have common module on my app that retrieves data from remote server and have get methods to export the retrieved data to other modules.

Lets assume that this module's name is MyData:

define([], function(){

    return function(opts) {
        var data = null;

        // go get data with ajax
        var getData = function(){
            $.ajax("getData").done(function(response){
                data = response;
            });
        };

        getData();

        // return public api
        if (arguments.length !== 0) {
            var method = arguments[0];
            switch (method) {
                case "get": return data;
            }
        };

    };

});

The problem is when I define other modules that use MyData, everytime it would create a new instance of MyData, causing it to retrieve the data from the server each time.

I could use web storage (or other global variable) to store the returned data, but it seems like a bad solution.

Is there any way to force RequireJS to create only once instance?

P.S: In my project I user KnockoutJS, and the data variable is an ko.observable, so maybe knockout has a solution for my situation?

like image 943
IgalSt Avatar asked Oct 04 '12 16:10

IgalSt


1 Answers

RequireJS already loads each module once. You just need to restructure your code a bit:

// myModule.js
define(function() {
    // The dataFetch Promise will be initialized when this module
    // is loaded for the first time.
    var dataFetch = $.ajax("getData");

    return {
        getData: function () {
            // Return the Promise interface and let callers use the
            // .done, .fail etc. methods on it
            return dataFetch;
        }
    };
});

Usage:

define([ "myModule" ], function (myModule) {
    myModule.getData().done(function (data) {
        // use the data
    });
});

By using the Promise interface returned by $.ajax, you can ensure asynch access to data that's fetched only once.

BTW, perhaps the pattern that you're trying to implement is a Model.

like image 79
Ates Goral Avatar answered Nov 14 '22 23:11

Ates Goral