Angular UI-Router - 在状态更改时刷新延迟加载的嵌套ui-view

时间:2022-02-21 12:16:18

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.

我是新手使用ui-router,并且在使用延迟加载的嵌套ui-view时遇到了一些困难。我已经尝试了很多东西,虽然我想我已经接近了,但是我无法完全开始工作,所以无论谁修复下面分享的那个,都会得到正确答案。

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.

- 首先,require.js引导主应用程序,index.html包含两个ui视图,一个用于导航,一个用于主要内容部分。主内容部分包含各种项目组合项(plnkr中的Test1),当选择一个时,它们被延迟加载(使用ocLazyLoad)到主内容部分。

-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.

- 主应用程序模块在其配置方法中定义各种状态,包括根据其ID并基于命名约定加载项目组合项的状态。

-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.

- 当单击Test1时,它的主模块是延迟加载的,并且该模块定义了它自己的状态,Test1有自己的index.html和它自己的嵌套ui-view。值得注意的是,我还必须使用此模块的run方法来运行在$ timeout中包装$ state.go的函数,以便在最初单击Test1时使模板内容出现在嵌套的ui-view中。这很黑,无疑不是正确的方法,也许是问题的根源,我们很快就会看到。我也尝试将$ state.go放在一个服务中,但它没有起作用,因为我最终遇到了同样的问题。

-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.

- 最后,这里有事情破裂。如果从Test1内部,单击主导航中的Home,然后再次尝试单击Test1,则先前出现在嵌套ui视图中的模板内容不会出现(显然,因为模块的run函数只运行一次)。通过手动点击重新加载状态的链接可以很容易地重新显示它,但显然这是不可取的。

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

TL / DR - 主页 - >点击Test1 - >工作! - >单击主页 - >单击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:

延迟加载Test1主模块和状态:

(function() {

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

  $urlRouterProvider.otherwise('/');

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

})();

1 个解决方案

#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.

我不确定你想要实现什么,但将$ state.go置于运行块是他第一次和任何其他连续时间工作的原因。

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

为了解决这个问题,$ state.go调用了testsCtrl,同时添加$ state作为依赖注入

See my fixed plunker.

看我固定的plunker。

#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.

我不确定你想要实现什么,但将$ state.go置于运行块是他第一次和任何其他连续时间工作的原因。

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

为了解决这个问题,$ state.go调用了testsCtrl,同时添加$ state作为依赖注入

See my fixed plunker.

看我固定的plunker。