SPA using requirejs and jquery

1

Good community, I am trying to migrate a project using the require.js library to perform asynchronous modules, but I have encountered problems that I do not know how to solve. Trying to use variables to save templates such as

Index_Ctrl.js

define({

    titulo: "Probando AMD con Require.js y Jquery",
    cuerpo: "Esto es una muestra de como debe funcionar\n\
             require js y jquery, su configuracion, entre otras cosas\n\
             un estilo MVC."

}); 

Index_tpl.js

define(['IndexCtrl'], function (IndexCtrl){


var index_page = {

    template: function (){

        var titulo, cuerpo;

        titulo = IndexCtrl.titulo;
        cuerpo = IndexCtrl.cuerpo;

        var html = '<h1>'+ titulo +'</h1>'+
                   '<p>' + cuerpo + '</p>'+
                   '<button id="btn_menu">Menu</button>';

        $('#contenedor').append(html);
    }

};

return {
    template: index_page.template
};

});

index.html

<html>

<head>

    <title>AMD</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

</head>

<body>

    <div id="contenedor">

    </div>

    <script data-main="js/app/main" src="js/libs/require.js"></script>

</body>

</html>

main.js

require.config({
    baseUrl: 'js',

    paths : {
      jquery : ['libs/jquery-1.12.0.min',
               'libs/jquery-2.2.0.min'],
  IndexTpl: 'app/Index_Tpl',
  IndexCtrl: 'app/Index_Ctrl',
  MenuTpl: 'app/Menu_Tpl',
  MenuCtrl: 'app/Menu_Ctrl'
},

shim: {
    IndexTpl: ['jquery'],
    MenuTpl: ['jquery']
}


});

define(['IndexTpl', 'MenuTpl'], function (index, menu){


index.template();

});

I would like you to click on a button a module to use another template that are the following

Menu_Tpl.js

define(['MenuCtrl'], function (MenuCtrl){

    var menu_page = {

        template_m: function (){

            var titulo, cuerpo;

            titulo = MenuCtrl.titulo;
            cuerpo = MenuCtrl.cuerpo;

            var html = '<h1>'+ titulo +'</h1>'+
                       '<p>' + cuerpo + '</p>'+
                       '<button id="btn_index">Index</button>';

            $('#contenedor').append(html);
        }

    };

    return {
        template_m: menu_page.template_m
    };

});

Menu_Ctrl.js

define({

    titulo: "Probando AMD con Require.js y Jquery",
    cuerpo: "Este es el menu de prueba."

});
    
asked by Pedro Miguel Pimienta Morales 06.02.2016 в 00:06
source

1 answer

1

You have to make several changes to make it work, I'll detail them below

File main.js

Replace the last define with a require because it is the way to obtain the dependencies

require.config({
    baseUrl: 'js',

    paths : {
    jquery : ['libs/jquery-1.12.0.min',
            'libs/jquery-2.2.0.min'],
    IndexTpl: 'app/Index_Tpl',
    IndexCtrl: 'app/Index_Ctrl',
    MenuTpl: 'app/Menu_Tpl',
    MenuCtrl: 'app/Menu_Ctrl'
    },

    shim: {
        IndexTpl: ['jquery'],
        MenuTpl: ['jquery']
    }

});

require(['IndexTpl'], function (index){

    index.template();

});

File Index_Tpl.js

Capture the click of the button and use require to get the reference to the template index and run the template You should also change the way to identify the button by changing the attribute id by an attribute data

define(['IndexCtrl'], function (IndexCtrl){      

    var index_page = {

        template: function (){

            var titulo, cuerpo;

            titulo = IndexCtrl.titulo;
            cuerpo = IndexCtrl.cuerpo;

            var html = '<h1>'+ titulo +'</h1>'+
                    '<p>' + cuerpo + '</p>'+
                    '<button data-action="btn_menu">Ir al Menu</button>';

            $('#contenedor').html(html);

            $('button[data-action="btn_menu"]').on('click', function (){        
                require(['MenuTpl'], function(menu){ 
                    menu.template();
                });                            
            }); 

        }        
    };   

    return {
        template: index_page.template
    };

});

File Menu_Tpl.js

We would make the same changes as in Index_tpl.js

define(['MenuCtrl'], function (MenuCtrl){

    var menu_page = {

        template: function (){

            var titulo, cuerpo;

            titulo = MenuCtrl.titulo;
            cuerpo = MenuCtrl.cuerpo;

            var html = '<h1>'+ titulo +'</h1>'+
                    '<p>' + cuerpo + '</p>'+
                    '<button data-action="btn_index">Ir al index</button>';

            $('#contenedor').html(html);

            $('button[data-action="btn_index"]').on('click', function (){        
                require(['IndexTpl'], function(index) {
                    index.template();  
                });                            
            }); 
        }

    };

    return {
        template: menu_page.template
    };

});

Full code is uploaded to GitHub

Recommendations

  • Something we have to keep in mind when we face a problem is that we should not reinvest the wheel and I think that is what you could be doing your (apology for being so direct, I do not pretend to offend you, it's something that I also say to myself)

  • I recommend you use one of the many SPA frameworks that exist, AngularJs , Aurelia , ... provide numerous advantages (template system, binding, routing, dependency injection, ...

  • Personally I chose AngularJs because it is very widespread in the community, it is very powerful and it urged you to have your code ordered with the management of modules, dependency injection.

  • As for the asynchronous load of elements (one of the functions of requirejs ) it has to be very justified (for example for very very large applications) because, among other things, it adds a lot of complexity.

answered by 06.02.2016 / 01:15
source