使用ui-router解决延迟加载angularjs控制器

时间:2014-08-30 12:20:39

标签: angularjs requirejs angular-ui-router

我正在尝试使用angular.js,ui-router和require.js并感到非常困惑。我尝试按照本教程http://ify.io/lazy-loading-in-angularjs/进行操作。首先,让我告诉你我的代码:

app.js =>

var app = angular.module('myApp', []);
app.config(function ($stateProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
    $stateProvider.state('home',
        {
            templateUrl: 'tmpl/home-template.html',
            url: '/',
            controller: 'registration'
            resolve: {
                deps: function ($q, $rootScope) {
                    var deferred = $q.defer(),
                        dependencies = ["registration"];
                    require(dependencies, function () {
                        $rootScope.$apply(function () {
                            deferred.resolve();
                        });
                    })
                    return deferred.$promise;
                }
            }
        }
    );
    app.lazy = {
        controller: $controllerProvider.register,
        directive: $compileProvider.directive,
        filter: $filterProvider.register,
        factory: $provide.factory,
        service: $provide.service
    };
});

现在我的registration.js我有以下代码:

define(["app"], function (app) {
    app.lazy.controller("registration" , ["$scope", function ($scope) {
        // The code here never runs
        $scope.message = "hello world!";
    }]);
});

一切运行良好,即使是registration.js中的代码也会运行。但问题是控制器功能内部的代码永远不会运行,我得到错误 错误:[ng:areq] http://errors.angularjs.org/1.2.23/ng/areq?p0=registration&p1=not一个函数,未定义

这似乎我的代码没有成功注册控制器功能。任何想法?

P.S。在ui-router docs中,它被称为“如果这些依赖项中的任何一个是promise,它们将在实例化控制器并触发$ routeChangeSuccess事件之前被解析并转换为值。”但是如果我把deferred.resolve();来自timeOut中提到的代码并在说出5秒之后运行它,我的控制器代码运行并且我的视图在解析之前呈现,Strange。

3 个答案:

答案 0 :(得分:2)

似乎我遇到了完全相同的问题,遵循您所做的完全相同的教程,但使用ui-router。我的解决方案是:

  1. 确保app.controllerProvider可用于延迟控制器脚本。看起来你使用app.lazy {...}做了这个,这是一个非常好的触摸BTW:)
  2. 确保懒惰的ctrl脚本使用define()而非require()我无法通过您的代码告诉您是否已完成此操作。
  3. 以下是我使用公共app.controllerProvider方法的ui-router设置:

    app.config(function ($stateProvider, $controllerProvider, $filterProvider, $provide, $urlRouterProvider) {
    
      app.lazy = {
        controller: $controllerProvider.register,
        directive: $compileProvider.directive,
        filter: $filterProvider.register,
        factory: $provide.factory,
        service: $provide.service
      };
    
      $urlRouterProvider.otherwise('/');
    
      $stateProvider
    
        .state('app', {
          url:'/',
        })
    
        .state('app.view-a', {
          views: {
            'page@': {
              templateUrl: 'view-a.tmpl.html',
              controller: 'ViewACtrl',
              resolve: {
                deps: function ($q, $rootScope) {
                  var deferred = $q.defer();
    
                  var dependencies = [
                    'view-a.ctrl',
                  ];
    
                  require(dependencies, function() {
                    $rootScope.$apply(function() {
                      deferred.resolve();
                    });
                  });
    
                  return deferred.promise;
                }
              }
            }
          }
        });
    });
    

    然后在我的懒惰加载控制器中,我注意到我必须使用require(['app']),如下所示:

    define(['app'], function (app) {
    
      return app.lazy.controller('ViewACtrl', function($scope){
         $scope.somethingcool = 'Cool!';
      });
    
    });
    

    GitHub上的来源:https://github.com/F1LT3R/angular-lazy-load

    关于Plunker的演示:http://plnkr.co/edit/XU7MIXGAnU3kd6CITWE7

答案 1 :(得分:0)

将您的状态更改为''应该可以解决问题。 ''是根example.com/'/'example.com/#/

答案 2 :(得分:0)

我来给我2美分。我看到你已经解决了,如果其他人遇到类似的问题,我只想添加评论。

我遇到了一个非常类似的问题,但是我的部分代码等待DOM加载,所以我直接调用它(不使用“$(document).ready”)并且它有效。

$(document).ready(function() { /*function was being called here*/ });

这解决了我的问题。可能是一个不同的情况,但我遇到了同样的错误。