Angularjs - Modularize a code to be reusable in multiple projects

Asked

Viewed 659 times

4

Next person, I am developing a webapp where I have a very wide administrative area, with several functions. In another project I closed a few days ago, I also requested an administrative area with several functions that are similar to the one I’m already developing, such as a ticket system, for example.

I started to develop a new module (first time I try a module that can be reusable) however, I have no experience in it and I know it can be improved.

What I own?

At the moment I have a code, already functional, but it has some dependencies that I know can be improved. This is a very bare example of the code:

angular.module('agChecklist',[])
.run(['$rootScope','$stateParams','factList', function ($rootScope,$stateParams,factList) {
    //... algumas definições iniciais com $rootScope ...\\
}])

.factory('factList', ['localStorageService', function (localStorageService) {
    var _getCache = function() {
        return JSON.parse(localStorageService.get("list"));
    };

    return {
        getCache: _getCache
    };

    //... outras factorys ...\\
}])

.controller('ListCtrl',
['$rootScope','$scope','$stateParams',...[mais]...,
function($rootScope,$scope,$stateParams,...[mais]...) {
    $scope.addItem = function(event) {
        //adiciona item para a lista
    };

    $scope.removeItem = function(event) {
        //remove item da lista
    };

    //... mais funções que o usuário pode executar ...\\
}]);

In this case, it would be a module that adds products to a list to make a service order Checklist, etc. Simple thing.

The "problem"

In fact it is not a problem, but an optimization of code.
Currently when I need to use this Checklist I need to set the controller ListCtrl in or in the views I need it.

What ends up creating a very complex need for checks, because there are initial definitions that another controller would need to read before starting. For example, when refreshing, it reloads the cookie and assembles the list of where the user left off. Then this setting should happen before another controller. Otherwise the application would not work (at the moment it is ok).

Another reason is that the module is not loaded when starting the app. I am using the module ocLazyLoad that will load all files from the module CheckList only in the views I need.

What I have noticed

Analyzing other modules, I noticed that it is well using the .run, .factory, .directive and .service.

  • .run: used for initial definitions, such as empty initial array, etc;
  • .Factory: for external api request (normally);
  • .Directive: to create the ui modules that will create user interaction with the app;
  • .service: To manage the functions that the user calls, etc. All function behavior and communication between user interaction with the app’s interface and responses;

With that my doubt is the following?

  • How should I proceed to create a reusable module in other projects from the code I already have?
  • What would be the best practices for the creation of modules?
  • Is this really the best way? Or are there other better/easier/more correct ones, etc..?

Any consideration and/or opinion you may have, please share! I really want to improve this code development.

1 answer

3


Some important points on the definition of reusable modules:

  • The module name cannot be something simplistic that can already exist in the application (this would generate conflicts at the angle), many developers put their last names at the beginning of the module name, such as "trinity.agCheckList"
  • The same rule above, goes for controllers, in the end they are packed all together in Angular.

The flow of run is ideal for checking before starting a module, although many dependencies such as cookies that are not created by this module, encourage non-reuse, which is totally inadvisable.

On the definition of routes, your module can do it, so it would already inject the previously defined route, but particularly, this is very strange, because there will be cases where the system may not use the same route system, or so little lazyLoad.

As to the definition of service and factory, it is partially correct, the truth is that these two in the angular serve for practically the same thing, so much so that in Angular 2 will be joined in only one.

On the question asked in the comments regarding controller vs diretivas, i particularly believe that the initial idea should not be misrepresented, directives are for reusable components, if you can actually extract the behavior of that component, so that it does not depend on anything else from your system, then surely it must become a directive, if it fails, it is intimately connected and probably must be part of a controller. Of course that’s opinion, angular allows controllers to become directives, as they have controllers internally, but directives in Angular lose in performance to controllers in many cases. I leave the stack link in English on the subject: https://stackoverflow.com/questions/18757679/angularjs-directives-vs-controllers

  • Right. Perfect! Now one last question. I’ve seen modules that don’t use .controller but yes directives (with <i>templates</i> UI - the 'visual' is not the problem - e.g.: 'Add item' button that calls the function addItem) that it is they who make the 'calls' of the functions and these are executed within a .service. Does this flow get better? What I noticed with this use is the freedom that we have not need to define the controller in the webapp, so the module is more free to be used throughout the app.

  • I supplemented the answer with this question.

  • I managed to understand the general ideal. In my case I will have both situations. One where I can be independent of other areas, like a shopping cart and another where I would be dependent, like a sales report. But then, in the case of the cart, how could I create a Directive that calls a function from a service? Just the part of the function even if I have doubt. Example: identify which was clicked and call the function by passing some parameters, id, name, value, for example.

  • Your directive template, will have an onClick() event, which will trigger the controller of this directive, there is a normal flow, you just make the call to the injected service.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.