6

I'm new to using ui-router and am having some difficulty with a lazy loaded nested ui-view. I've tried a number of things and though I imagine I've come close, I can't quite get it to work, so whoever fixes the plunker shared below will be awarded the correct answer.

Plunker

-Firstly, require.js bootstraps the main application, and index.html contains two ui-views, one for the navigation, and one for the main content section. The main content section contains various portfolio items (Test1 in plnkr) that are lazy loaded (with ocLazyLoad) into the main content section when one is selected.

-The main app module defines the various states in its config method, including a state to load the portfolio item according to its ID and based on a naming convention.

-When Test1 is clicked, its main module is lazy loaded, and this module defines its own states, and Test1 has its own index.html with its own nested ui-view. Worth noting is that I've also had to use this module's run method to run a function that wraps $state.go in $timeout, to get template content to appear in the nested ui-view when Test1 is initially clicked. This is hackish and undoubtedly not the right approach and perhaps the source of the issue, as we'll see shortly. I also tried to put the $state.go in a service but it didn't make a difference as I ultimately ran into the same problem.

-Finally, here's where things break. If from inside Test1, you click on Home in the main nav, then try clicking on Test1 again, the template content that appeared previously in the nested ui-view doesn't appear (obviously, since the module's run function only runs once). It's easy to make it reappear by manually clicking on a link that reloads the state, but obviously this isn't desirable.

TL/DR -- Home -> Click on Test1 -> Working! -> Click Home -> Click Test1 -> Breaks!

Main app module and states:

(function() {

  angular.module('myApp', [
  'ui.router',
  //'door3.css',
  'oc.lazyLoad'
])
.config(function($ocLazyLoadProvider, $stateProvider, $urlRouterProvider) {

  $urlRouterProvider.otherwise('/');

  $stateProvider
    .state('root', {
      url: '/',
      views: {
        'nav': {
          templateUrl: 'views/static/nav.html'
        },
        'content': {
          templateUrl: 'views/portfolio.html'
        }
      }
    })
    .state('root.home', {
      url: 'home',
      views: {
        'content@': {
          templateUrl: 'views/portfolio.html'
        }
      }
    })
    .state('root.about', {
      url: 'about',
      views: {
        'content@': {
          templateUrl: 'views/about.html'
        }
      }
    })
    .state('root.portfolio', {
      url: ':id',
      views: {
        'content@': {
          // css: function($stateParams) {
          //   return '/portfolio/' + $stateParams.id + '/css/master.css';
          // },
          templateUrl: function($stateParams) {
            return 'portfolio/' + $stateParams.id + '/index.html';
          },
          resolve: {
            load: function($stateParams, $ocLazyLoad) {
              return $ocLazyLoad.load({
                files: ['portfolio/' + $stateParams.id + '/js/mainModule.js']
              });
            }
          }
        }
      }
    });

});

})();

Lazy loaded Test1 main module and states:

(function() {

  angular.module('testingApp', [{
  files: [
    'portfolio/testing/controllers/testingCtrl.js'
  ]
}])
.config(function($stateProvider, $urlRouterProvider) {

  $urlRouterProvider.otherwise('/');

  $stateProvider
    .state('root.portfolio.testing', {
      url: '/',
      views: {
        '[email protected]': {
          templateUrl: 'portfolio/testing/views/testfile.html',
          controller: 'testingCtrl',
          controllerAs: 'test'
        }
      }
    })
})
.run(function($state, $timeout) {
  $timeout(function() {
    $state.go('root.portfolio.testing');
  }, 0);
});

})();
1

1 Answer 1

1

I am not sure what you are trying to achieve but putting $state.go into run block was a reason why it worked the first time and any other consecutive time.

The reason is that run block is run only once at the time when module loads and module is loaded only once.

To fix this move $state.go call into testingCtrl while adding $state as a dependency injection

See my fixed plunker.

Sign up to request clarification or add additional context in comments.

2 Comments

This works as it should, and therefore I'll award it the correct answer. Strangely though, it still doesn't solve my issue in the more fleshed out version of my project, which is baffling. I recall trying different variations of your proposed fix and it either not working at all, or running into infinite loop issues. Something else is clearly amiss, and I'll report back if I need help after figuring out what that is.
smh... changing the <body> to <div> inside the nested index.html file is what finally fixed it. Thanks for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.