Cargando html y Controller desde el servidor y creando estados dinámicos UI - enrutador

Estoy buscando una solución para cargar el contenido de mi aplicación dinámicamente desde el servidor.

Mi escenario:

Digamos que tenemos 2 usuarios (A y B), mi aplicación consta de diferentes módulos como, por ejemplo, una lista de compras y una calculadora, ahora mi objetivo sería que el usuario inicie sesión en mi aplicación desde la base de datos obtengo los derechos de usuario y dependiendo de qué derechos él tiene, cargaría el html para las vistas y los archivos del controlador para la parte lógica del Servidor, al hacerlo crearía los estados necesarios para el html y ctrl. Básicamente, mi aplicación es muy pequeña, consistente con el inicio de sesión y todo lo demás se extrae del servidor dependiendo de los derechos de usuario.

Lo que uso:

CórdobaAngularJsMarco iónico

Por qué necesito que sea todo dinámico:

1) La posibilidad de tener una aplicación que contenga solo la lógica de inicio de sesión, por lo que al corregir errores o agregar módulos, solo tengo que agregar los archivos al servidor, le doy al usuario el derecho y está allí sin necesidad de actualizar la aplicación.

2) El usuario solo tiene la funcionalidad que necesita, no necesita tenerlo todo cuando solo tiene el derecho para 1 módulo.

3) La aplicación crece mucho en este momento, lo que significa que cada módulo tiene entre 5 y 10 estados, con su propio HTML y controladores. actualmente hay 50 módulos diferentes planeados para que pueda hacer los cálculos.

Miré esto para obtener algo de inspiración:

AngularJS, ocLazyLoad y carga de estados dinámicos

Lo que probé hasta ahora:

Creé 1 archivo Html que contiene todo el módulo, así que solo tengo 1 solicitud http:

Digamos que esta es mi respuesta del servidor después de que el usuario inició sesión

Parte HTML:

var rights= [A,B,C,D]

angular.forEach(rights, function (value, key) {
     $http.get('http://myServer.com/templates/' + value + '.html').then(function (response) {
        //HTML file for the whole module
        splits = response.data.split('#');
        //Array off HTMl strings
        for (var l = 1; l <= splits.length; l++) {  
          //Putting all Html strings into templateCache                              
          $templateCache.put('templates/' + value +'.html', splits[l - 1]);

          }
        }
     });

Parte del controlador:

var rights= [A,B,C,D]

angular.forEach(rights, function (value, key) {
     $http.get('http://myServer.com/controller/' + value + '.js').then(function (response) {
        // 1 file for the whole module with all controllers
        splits = response.data.split('#');
        //Array off controller strings
        for (var l = 1; l <= splits.length; l++) {  
          //Putting all Controller strings into templateCache                              
          $templateCache.put('controllers/' + value +'.js', splits[l - 1]);

          }
        }
     });

Después de cargar los controladores, intento registrarlos:

$controllerProvider.register('SomeName', $templateCache.get('controllers/someController));

Lo que no funciona ya que esto es solo una cadena ...

Definición de los proveedores:

.config(function ($stateProvider, $urlRouterProvider, $ionicConfigProvider, $controllerProvider) {

  // turns of the page transition globally
    $ionicConfigProvider.views.transition('none');
    $stateProviderRef = $stateProvider;
    $urlRouterProviderRef = $urlRouterProvider;
    $controllerProviderRef = $controllerProvider;


    $stateProvider

    //the login state is static for every user
  .state('login', {
      url: "/login",
      templateUrl: "templates/login.html",
      controller: "LoginCtrl"
  });

   //all the other states are missing and should be created depending on rights

$urlRouterProvider.otherwise('/login');


});

Parte del enrutador Ui:

//Lets assume here the Rights Array contains more information like name, url...
    angular.forEach(rights, function (value, key) {
       //Checks if the state was already added
         var getExistingState = $state.get(value.name)

         if (getExistingState !== null) {
              return;
         }

          var state = {
             'lang': value.lang,
             'params': value.param,
             'url': value.url,
             'templateProvider': function ($timeout, $templateCache, Ls) {
               return $timeout(function () {
               return $templateCache.get("templates" + value.url + ".html")
                                    }, 100);
                                },
             'ControllerProvider': function ($timeout, $templateCache, Ls) {
                return $timeout(function () {
                return $templateCache.get("controllers" + value.url + ".js")
                                        }, 100);
                                    }

                            $stateProviderRef.state(value.name, state);
                        });

                        $urlRouter.sync();
                        $urlRouter.listen();

Situación hasta ahora:

Me las arreglé para cargar los archivos html y almacenarlos en templateCache, incluso cargarlos, pero solo si los estados estaban predefinidos. Lo que noté aquí fue que a veces podemos decir cuando elimino un elemento de una Lista y vuelvo a Ver el elemento estaba allí nuevamente, tal vez esto tiene algo que ver con el caché, no estoy realmente seguro ...

Me las arreglé para cargar los archivos del controlador y guardar los controladores en templateCache, pero realmente no sé cómo usar el $ ControllerPrioviderRef.register con mis cadenas almacenadas ...

La creación de los estados funcionó, pero el controlador no encajó, por lo que no pude abrir ninguna vista ...

PD: también miré require.js y OCLazyLoad, así como este ejemploejemplo de controlador dinámico

Actualizar:

Bien, logré cargar elHtml , crea elState con elController todo parece funcionar bien, excepto que el controlador no parece funcionar en absoluto, no hay errores, pero parece que no se ejecuta nada de la lógica del controlador. Actualmente, la única solución para registrar el controlador desde el archivo descargado anterior era usareval(), que es más un truco que una solución adecuada.

Aquí el código:

.factory('ModularService', ['$http', ....., function ( $http, ...., ) {
    return {
        LoadModularContent: function () {
            //var $state = $rootScope.$state;

            var json = [
            {
                module: 'Calc',
                name: 'ca10',
                lang: [],
                params: 9,
                url: '/ca10',
                templateUrl: "templates/ca/ca10.html",
                controller: ["Ca10"]

            },
            {
                module: 'SL',
                name: 'sl10',
                lang: [],
                params: 9,
                url: '/sl10',
                templateUrl: "templates/sl/sl10.html",
                controller: ['Sl10', 'Sl20', 'Sl25', 'Sl30', 'Sl40', 'Sl50', 'Sl60', 'Sl70']

            }
            ];

            //Load the html 
            angular.forEach(json, function (value, key) {
            $http.get('http://myserver.com/' + value.module + '.html')
            .then(function (response) {
               var splits = response.data.split('#');
               for (var l = 1; l <= value.controller.length; l++) {
                 $templateCache.put('templates/' + value.controller[l - 1] + '.html', splits[l - 1]);
                    if (l == value.controller.length) {
                       $http.get('http://myserver.com//'+value.module+'.js')
                       .then(function (response2) {
                          var ctrls = response2.data.split('##');
                          var fullctrl;
                          for (var m = 1; m <= value.controller.length; m++){

                            var ctrlName = value.controller[m - 1] + 'Ctrl';                                                                             

                            $controllerProviderRef
                            .register(ctrlName, ['$scope',...., function ($scope, ...,) {    
                                   eval(ctrls[m - 1]);
                            }])
                            if (m == value.controller.length) {

                              for (var o = 1; o <= value.controller.length; o++) {
                               var html = $templateCache
                              .get("templates/" + value.controller[o - 1] + ".html");

                                  var getExistingState = $state.get(value.controller[o - 1].toLowerCase());

                                 if (getExistingState !== null) {
                                                            return;
                                                        }

                                var state = {
                                 'lang': value.lang,
                                 'params': value.param,
                                 'url': '/' + value.controller[o - 1].toLowerCase(),
                                 'template': html,
                                 'controller': value.controller[o - 1] + 'Ctrl'
                                 };


                                  $stateProviderRef.state(value.controller[o - 1].toLowerCase(), state);
                                 }
                               }
                             }
                          });
                        }
                     }                            
                 });                      
            });
            // Configures $urlRouter's listener *after* your custom listener

            $urlRouter.sync();
            $urlRouter.listen();

        }
    }
}])

Cualquier ayuda apreciada

Respuestas a la pregunta(4)

Su respuesta a la pregunta