Angular缺少resumeBootstrap函数

时间:2014-09-04 15:06:18

标签: javascript angularjs

我目前正在尝试使用RequireJS设置一个新的AngularJS项目。我已经开始了angularjs-requirejs-seed项目。我过去使用angular / require完成了一个项目,但我还没有能够使用" NG_DEFER_BOOTSTRAP"办法。

这是我的main.js文件,

'use strict';

require.config({
    paths: {
        jquery: "bower_components/jquery/dist/jquery",
        angular: "bower_components/angular/angular",
        angularRoute: "bower_components/angular-route/angular-route.min",
        angularMocks: "bower_components/angular-mocks/angular-mocks.min",
        text: "bower_components/requirejs-text/text",
        compApp: "components/app",
    },
    shim: {
        'angular' : {'exports' : 'angular'},
        'angularRoute': ['angular'],
        'angularMocks': {
            deps:['angular'],
            'exports':'angular.mock'
        }
    },
    priority: [
        "angular"
    ]
});

//http://code.angularjs.org/1.2.1/docs/guide/bootstrap#overview_deferred-bootstrap
window.name = "NG_DEFER_BOOTSTRAP!";

require([
    'angular',
    'compApp/app'
], function(angular, app) {
    var $html = angular.element(document.getElementsByTagName('html')[0]);

    angular.element().ready(function() {
        angular.resumeBootstrap([app['name']]);
    });
});

当我运行此命令时,我在resumeBoostrap行上收到错误undefined is not a function。当我调试应用程序并在resumeBootstrap行上设置断点时,我发现angular缺少resumeBootstrap方法。但是window.name正确显示NG_DEFER_BOOTSTRAP。此外,如果我删除resumeBoostrap方法并只执行angular.bootstrap,那么该应用程序可以正常工作,告诉我其他一切都很好。

这是我的html文件,

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->

        <link rel="stylesheet" href="css/normalize.css">
        <link rel="stylesheet" href="css/main.css">
        <script src="js/modernizr.min.js"></script>
    </head>

    <body>
        <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->

        <h1>AngularJS + RequireJS</h1>
        <ul class="menu">
            <li><a href="#/view1">view1</a></li>
            <li><a href="#/view2">view2</a></li>
        </ul>

        <div ng-view></div>

        <script data-main="main" src="bower_components/requirejs/require.js"></script>  
    </body>
</html>

3 个答案:

答案 0 :(得分:6)

根据angular documentation for bootstrap

  

如果window.name包含前缀NG_DEFER_BOOTSTRAP!当调用angular.bootstrap时,引导过程将暂停,直到调用angular.resumeBootstrap()。

     

angular.resumeBootstrap()接受一个可选的模块数组,这些模块应该添加到应用程序即将被引导的原始模块列表中。

这是我在requirejs应用程序中推迟角度初始化的片段:

window.name = "NG_DEFER_BOOTSTRAP!";

define(['angular', 'domReady', 'app'], function(ng, domReady){
    domReady(function(document){
        ng.bootstrap(document, ['app']);
        ng.resumeBootstrap();
    })
});

答案 1 :(得分:3)

我花了很多时间在这个上面。问题是由resumeBootstrap方法的惰性定义引起的。 angular.js通过JQLite检测dom。当文档加载时,它会触发一个定义resumeBootstrap方法的方法。问题是您无法在domready和JQLite就绪之间强制执行处理顺序,如果在定义方法之前已经满足了您的依赖关系,那么您就遇到了麻烦。

解决方法是强制javascript在resumeBootstrap调用之前执行所有事件处理程序。我使用了setTimeout方法,例如:setTimeout(angular.resumeBootstrap,0)。

http://javascript.info/tutorial/events-and-timing-depth#the-settimeout-func-0-trick

希望它有所帮助!

答案 2 :(得分:1)

这是一个古老的问题,但是我遇到了对(半)旧版应用程序的需求。我没有使用DOM Ready事件或任何settimeout()恶作剧,而是检查了源代码并发现了此未记录的功能:https://github.com/angular/angular.js/blob/master/src/Angular.js#L1853

if (isFunction(angular.resumeDeferredBootstrap)) {
    angular.resumeDeferredBootstrap();
}

此内容已在以下提交中添加:https://github.com/angular/angular.js/commit/c69caa7beee4e920f8f587eb3e943be99864a14f。 由于未记录此文件,因此您应自行承担使用风险,但是我怀疑,由于angularjs在LTS中已经存在了一段时间,因此一切都会发生变化。

如果延迟了引导过程,则此代码将运行,因此是放置angular.resumeBootstrap()调用的理想钩子函数。

示例:

angular.resumeDeferredBootstrap = function () {
    // perform actions that need to happen before bootstrapping here
    angular.resumeBootstrap();
    // you could also do some async work in here and make sure bootstrapping happens after
    someAsyncFunctionThatReturnsAPromise().then(function () {
        angular.resumeBootstrap();
    });
};