Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS, ocLazyLoad & loading dynamic States

app

define(['angular', 'angular-ui-router', 'ocLazyLoad', 'config/common', 
        'layout/services/menuService'],

function(angular) {
    'use strict';
    var $stateProviderRef = null;
    var $urlRouterProviderRef = null;
    return  angular.module('app', ['ui.router', 'oc.lazyLoad', 'app.common', 'app.layout']);
});

app.config

define(['app'],function(app){
app.config(function($locationProvider, $stateProvider, $urlRouterProvider, $ocLazyLoadProvider) {
    $urlRouterProviderRef = $urlRouterProvider;
    $stateProviderRef = $stateProvider;

    $urlRouterProviderRef.otherwise('/');
    $locationProvider.html5Mode({enable: true, requireBase: false}); //.hashPrefix('!');
    $ocLazyLoadProvider.config({
        events: true,
        debug: false
    });   }); });

app.run

define(['app'],function(app) {
app.run(function ($q, $rootScope, $state, $window, menuSvc) {
    menuSvc.all().success(function(viewStates) {
        var startUp = undefined;
        angular.forEach(viewStates, function(viewState, key){
            var viewStateUrl = undefined;
            if (viewState.isStartUp == true && startUp == undefined) {
                startUp = viewState.name;
            }

            var state = {
                "url": viewState.url,
                "name": viewState.name,
                "views": []
            }

            angular.forEach(viewState.views, (function(view) {
                var myView = {
                    "controller" : view.controller,
                    "templateUrl" : view.templateUrl,
                    "resolve" : { }
                };

                myView.resolve.loadController = function($ocLazyLoad)
                {
                    return $ocLazyLoad.load(
                        {
                            "name": view.moduleName,
                            "files": view.controllerFiles
                        })
                };

                state.views[view.viewName] = myView ;
            }));

            $stateProviderRef.state(viewState.name, state);
        })
        $state.go(startUp);
    })
}); });

Solved:

The error was in a combination of areas. The complete solution is below. I am not happy about the solution to this outcome as mentioned below and welcome ideas. Basically I would have preferred a more agnostic binding of the resolve method to my states in the app.run file.


1 Answers

I have this working, although I am not quite happy with the code and I will explain at the end. First off, I found a path to my solution from this Stackoverflow Prior Question

1. app.js

The only change I made from above was to add the ShellCtrl location:

define(
[
    'angular', 'angular-ui-router', 'ocLazyLoad', 'config/common',
    'layout/services/menuService', 'layout/controllers/ShellCtrl'],
  
    .....

2. app.config:

Nothing changed from above.

3. app.run

define(['app'],function(app) {
app.run(function ($q, $rootScope, $state, $window, menuSvc) {
    menuSvc.all().success(function(states) {
        angular.forEach(states, function (state) {>                
            try{
               /// for the Header
                state.views.header.resolve[state.views.header.data.controllerAlias] =
                 function($ocLazyLoad){
                    return $ocLazyLoad.load({
                        "name": state.views.header.data.controllerAlias,
                        "files": state.views.header.data.controllerFiles})};

               /// for the Footer
                state.views.footer.resolve[state.views.footer.data.controllerAlias] =

                 function($ocLazyLoad){
                    return $ocLazyLoad.load({
                        "name": state.views.footer.data.controllerAlias,
                        "files": state.views.footer.data.controllerFiles})};
            }catch(e){

            }
            console.log(state);
            $stateProviderRef.state(state.name, state);
        })
      $state.go('app.dashboard');
    })
}); });

4. With this as my JSON:

[   { "name": "app", "abstract": true, "url": "", "templateUrl": "app/layout/views/tpl.shell.html", "controller": "ShellCtrl" },   {
"name": "app.dashboard",
"views": {
  "header": {
    "templateUrl": "app/layout/views/tpl.header.html",
    "controller": "HeaderCtrl as header",
    "resolve": {},
    "data": {
      "controllerAlias": "app.layout",
      "controllerFiles": [
        "app/layout/layout.module.js",
        "app/layout/controllers/HeaderCtrl.js"
      ]
    }
  },
  "footer": {
    "templateUrl": "app/layout/views/tpl.footer.html",
    "controller": "FooterCtrl as footer",
    "resolve": {},
    "data": {
      "controllerAlias": "app.layout",
      "controllerFiles": [
        "app/layout/layout.module.js",
        "app/layout/controllers/FooterCtrl.js"
      ]
    }
  }
}   }]

5. Shell.html

   <div data-ng-controller="ShellCtrl">{{shell.pageTitle}}
   <div data-ui-view="header"></div> 
   <div data-ui-view="footer"></div>
   </div> 

6 Sample Controller:

   angular.module('app.layout').controller('HeaderCtrl', HeaderCtrl);

/* @ngInject */
function HeaderCtrl($scope) {
    var header = this;
    header.pageTitle = 'Response coming from HeaderCtrl';
}

7. With this as the output:

enter image description here

What I do not like:

All components of my dashboard are interchangeable. Nothing is static. Depending on the "overall" view, the Header, Footer, SideMenu and Content all change. The link I mentioned above had only 1 interchangeable part, "the Feature" which I assume was main content.

I do not like the fact that I had to hard code each view in the my app.run relative to binding the resolve to each.

If someone knows how I can make this more agnostic, I would greatly appreciate input.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!