使用Angular ui-routing解析加载requirejs模块

时间:2017-02-15 15:41:06

标签: angularjs angular-ui-router requirejs

我试图使用require.js来延迟加载一些角度的依赖项,我遇到了一些问题。

我相信下面的代码应该尝试在角度需要之前加载寄存器控制器(通过angular-ui-router):

  .state('register', {
    url: '/register',
    class: 'login',
    title: 'Register',
    templateUrl: 'app/security/register.view.html',
    controller: 'RegisterController',
    controllerAs: 'register',
    resolve: {
      require: function ($q) {
        return $q(function (resolve, reject) {
          console.log('security/register.controller loading')
          require(['security/register.controller'], function () {
            console.log('security/register.controller loaded')
            resolve()
          })
        })
      }
    }
  })

但是当我从登录状态切换到寄存器状态时,我在控制台中得到以下输出:

RouteChanged Login
security/register.controller loading
security/register.controller loaded
RouteChanged Register
Error: [ng:areq] http://errors.angularjs.org/1.5.8/ng/areq?p0=RegisterController&p1=not%20aNaNunction%2C%20got%20undefined

因此,即使解析运行,角度也会抛出错误,说它无法找到RegisterController。

Here's a link to a plunker.如您所见,单击链接时未加载控制器,控制台中会显示错误消息。

3 个答案:

答案 0 :(得分:1)

我个人用ui路由器使用$ ocLazyLoad提供程序https://github.com/ocombe/ocLazyLoad

它更简单,效果很好。这是一个例子:

     .state('dashboards.dashboard_2', {
                url: "/dashboard_2",
                templateUrl: "views/dashboard_2.html",
                data: { pageTitle: 'Dashboard 2' },
                resolve: {
                    loadPlugin: function ($ocLazyLoad) {
                        return $ocLazyLoad.load([
                            {
                                serie: true,
                                name: 'angular-flot',
                                files: [ 'js/plugins/flot/jquery.flot.js', 'js/plugins/flot/jquery.flot.time.js', 'js/plugins/flot/jquery.flot.tooltip.min.js', 'js/plugins/flot/jquery.flot.spline.js', 'js/plugins/flot/jquery.flot.resize.js', 'js/plugins/flot/jquery.flot.pie.js', 'js/plugins/flot/curvedLines.js', 'js/plugins/flot/angular-flot.js', ]
                            },
                            {
                                files: ['js/plugins/jvectormap/jquery-jvectormap-2.0.2.min.js', 'js/plugins/jvectormap/jquery-jvectormap-2.0.2.css']
                            },
                            {
                                files: ['js/plugins/jvectormap/jquery-jvectormap-world-mill-en.js']
                            },
                            {
                                name: 'ui.checkbox',
                                files: ['js/bootstrap/angular-bootstrap-checkbox.js']
                            }
                        ]);
                    }
                }
            })

答案 1 :(得分:0)

试试这个:

resolve: {
      require: function ($q) {
        //tell ui-router to wait
        var deferred = $q.defer(); 
          console.log('security/register.controller loading')

          require(['security/register.controller'], function () {
            console.log('security/register.controller loaded')
            deferred.resolve()
          });
         return deferred.promise; 
      }

答案 2 :(得分:0)

事实证明问题在于我有缺陷的假设你可以在bootstrap之后添加一个控制器到角度,这显然你可以,就像你做pre-bootstrap一样。如果您在引导后添加它们,则需要缓存控制器提供程序的副本,然后向该提供程序注册控制器。我添加了以下代码:

var app = angular.module('app', ['ui.router'])

var cachedProviders = {}
  app.config(['$controllerProvider',
    function(controllerProvider) {
      cachedProviders.$controllerProvider = controllerProvider;
    }
  ]);
  $(function (){
    app.controller = function (name, controller) {
      console.log('Loading (using post-boostrap loader):', name)
      cachedProviders.$controllerProvider.register.apply(this, arguments)
    }
  })

到我的app模块文件,它开始工作。我不太确定这是否会产生负面影响,但现在它可以做我想要的。