从服务器加载html和Controller并创建动态UI - 路由器 [英] Loading html and Controller from server and creating dynamic states UI - router

查看:112
本文介绍了从服务器加载html和Controller并创建动态UI - 路由器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种从服务器动态加载我的应用内容的解决方案。

I am looking for a Solution to load my App Content dynamically from the Server.

我的场景:

假设我们有2个用户(A和B),我的应用程序包含不同的模块,比如说一个shoppingList和一个计算器,现在我的目标是用户从数据库登录我的应用程序我得到用户权限和依赖他有什么权利,我会从服务器加载视图的html和逻辑部分的控制器文件,同时这样做我将创建html和ctrl所需的状态。因此,基本上我的应用程序与Login一致,并且根据Userrights从服务器获取其他所有内容。

Lets say we have 2 Users (A and B), my App consists of different Modules like lets say a shoppingList and a calculator, now my goal would be the User logs into my App from the Database I get the User rights and depending what rights he has, i would load the html for the views and the controller files for the logic part from the Server, while doing that I would create the states needed for the html and ctrl. So basically my App is very small consistent of the Login and everything else is getting pulled from the Server depending on the Userrights.

我使用的是:


  1. Cordova

  2. AngularJs

  3. Ionic Framework

为什么我需要它全部动态:

Why I need it to be all dynamic:

1)拥有一个仅包含App的应用程序的可能性登录逻辑,所以当修复错误或添加模块时,我只需要将文件添加到服务器,为用户提供权利,而无需更新应用程序。

1)The possiblity to have an App that contains just the login logic, so when fixing bugs or adding Modules I only have to add the files to the server give the User the right for it and it is there without needing to update the app.

2)用户只有他需要的功能,当他只有1个模块的权利时,他不需要拥有一切。

2)The User only has the functionality he needs, he doesnt need to have everything when he only has the right for 1 module.

3)该应用程序此刻变得非常大,意味着每个模块都有5-10个状态,拥有自己的html和控制器。目前有50个不同的模块计划,所以你可以做数学。

3)The App grows very big at the moment, meaning every Module has like 5-10 states, with their own html and Controllers. currently there are 50 different Modules planned so you can do the math.

我看了这个以获得一些灵感:

I looked at this to get some inspiration:

AngularJS,ocLazyLoad&加载动态状态

到目前为止我尝试过:

我创建了1个Html文件,其中包含整个模块所以我只有1个http请求:

I created 1 Html file which contains the whole module so I only have 1 http request:

让我们说这是用户登录后来自服务器的响应

Lets say this is my response from the server after the User logged in

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]);

          }
        }
     });

控制器部分:

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]);

          }
        }
     });

加载控制器后我尝试注册它们:

After loading the Controllers I try to register them:

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

哪个不起作用,因为这只是一个字符串......

Which is not working since this is only a string...

定义提供者:

.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');


});

Ui-Router Part:

Ui-Router Part:

//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();

到目前为止的情况:

我有设法加载html文件并将它们存储在templateCache中,甚至加载它们但仅在状态是预定义的时候加载它们。我在这里注意到有时让我们说当我从列表中删除一个项目然后回到查看该项目时还有可能这与缓存有关我不太确定...

I have managed to load the html files and store them in the templateCache, even load them but only if the states were predefined.What I noticed here was that sometimes lets say when I remove an item from a List and come back to the View the item was there again maybe this has something to do with cache I am not really sure...

我已经设法加载控制器文件并将控制器保存在templateCache中但是我我真的不知道如何使用$ ControllerPrioviderRef.register与我存储的字符串...

I have managed to load the controller files and save the controllers in the templateCache but I dont really know how to use the $ControllerPrioviderRef.register with my stored strings...

创建状态确实有效但控制器不适合所以我无法打开任何视图...

Creating the states did work but the Controller didnt fit so i could not open any views...

PS:我还查看了require.js和OCLazyLoad以及此示例动态控制器示例

PS: I also looked at require.js and OCLazyLoad as well as this example dynamic controller example

更新:

好的,所以我设法加载 Html ,创建 控制器一切似乎都运行良好,除了控制器似乎根本不工作,没有错误,但似乎没有执行控制器逻辑。目前,从以前下载的文件中注册控制器的唯一解决方案是使用 eval(),这更像是一个黑客,然后是一个正确的解决方案。

Okay so I managed to load the Html , create the State with the Controller everything seems to work fine, except that the Controller does not seem to work at all, there are no errors, but it seems nothing of the Controller logic is executed. Currently the only solution to register the controller from the previous downloaded file was to use eval(), which is more a hack then a proper solution.

这里代码:

.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();

        }
    }
}])

任何帮助赞赏

推荐答案

好的,让我们从头开始。

Ok, so let's start from the beginning.

所有应用程序逻辑都应该包含在服务器上,并通过REST,SOAP或类似的API调用提供服务。通过这样做,您可以减少UI中内置的逻辑量,从而减轻客户端的压力。这基本上使您的客户端应用程序成为渲染代理,仅包含后端API提供的数据和逻辑的模型和视图。

All the application logic should be contained on the server and served via API-calls through REST, SOAP or similar. By doing so, you reduce the amount of logic built into the UI, which reduces the stress on the client. This basically makes your client app a rendering agent, containing only models and views for the data and logic served by the backend API.

正如foreyez在他/她的评论中所述,这对任何现代(或半现代)设备都不是问题。

As foreyez stated in his/her comment, this isn't an issue for any modern (or half-modern) device.

如果你坚持不立刻加载所有布局,你当然可以分开它们分为部分,您在登录后根据用户权限加载它们。通过这样做,您可以减少内存中数据的数量,即使这种改进最多也是可以怀疑的。

If you insist on not loading all of the layouts at once, you could of course separate them into partials, which you load after the login based on the user privileges. By doing so, you reduce the amount of in-memory data, even though the improvement would be doubtable, at best.

这篇关于从服务器加载html和Controller并创建动态UI - 路由器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆