Javascript 如何在requirejs中使用角度场景

Javascript 如何在requirejs中使用角度场景,javascript,angularjs,requirejs,angular-scenario,Javascript,Angularjs,Requirejs,Angular Scenario,当您的Angular应用程序在DOM ready上就绪时,Angular场景可以很好地工作。当使用requirejs或其他AMD库时,情况并非如此。如何在角度场景中添加对AMD的支持?您需要做的是覆盖默认的帧加载行为,并在AMD应用程序准备就绪时发出新事件 第一件事是在angular.bootstrap调用中添加以下行。角度场景需要此数据 angular.bootstrap(document, ['app']); var html = document.getElementsByTagName

当您的Angular应用程序在DOM ready上就绪时,Angular场景可以很好地工作。当使用requirejs或其他AMD库时,情况并非如此。如何在角度场景中添加对AMD的支持?

您需要做的是覆盖默认的帧加载行为,并在AMD应用程序准备就绪时发出新事件

第一件事是在angular.bootstrap调用中添加以下行。角度场景需要此数据

angular.bootstrap(document, ['app']);

var html = document.getElementsByTagName('html')[0];

html.setAttribute('ng-app', 'app');
html.dataset.ngApp = 'app';

if (top !== window) {
    top.postMessage({
        type: 'loadamd'
    }, '*');
}
接下来,在e2e runner中,必须包含这些行。如果它是一个外部脚本,则必须在角度场景之后加载,并且必须在DOM准备就绪之前对其进行解析:

/**
 *  Hack to support amd with angular-scenario
 */
(function() {
    var setUpAndRun = angular.scenario.setUpAndRun;

    angular.scenario.setUpAndRun = function(config) {
        if (config.useamd) {
            amdSupport();
        }
        return setUpAndRun.apply(this, arguments);
    };

    function amdSupport() {
        var getFrame_ = angular.scenario.Application.prototype.getFrame_;

        /**
         *  This function should be added to angular-scenario to support amd. It overrides the load behavior to wait from
         *  the inner amd frame to be ready.
         */
        angular.scenario.Application.prototype.getFrame_ = function() {
            var frame = getFrame_.apply(this, arguments);
            var load = frame.load;

            frame.load = function(fn) {
                if (typeof fn === 'function') {
                    angular.element(window).bind('message', function(e) {
                        if (e.data && e.source === frame.prop('contentWindow') && e.data.type === 'loadamd') {
                            fn.call(frame, e);
                        }
                    });
                    return this;
                }
                return load.apply(this, arguments);
            }

            return frame;
        };
    }
})();
最后,要启用amd配置,必须将属性ng useamd添加到angular场景的脚本标记中

<script type="text/javascript" src="lib/angular-1.0.3/angular-scenario.js" ng-autotest ng-useamd></script>

你现在准备好出发了


使用angular scenario v1.0.3进行测试,上述答案在我的场景中部分失败(angular 1.1.4,fresh Karma)。 在“调试”视图中,它运行正常,在“正常概述”页面中,它失败。我注意到一个额外的嵌套

我将代码更改为message to the parent iframe of the tested application

if (top !== window) {
    window.parent.postMessage({
        type: 'loadamd'
    }, '*');
}

公认的答案是绝对正确的,但遗憾的是,您必须将该代码放入页面中

因此,如果有帮助的话,我为karma创建了一个预处理器,将“修复”作为测试运行的一部分注入其中

代码: npm:

注意,这只在你通过业力服务文件时有效。如果您代理它们,它们不会经过预处理器。因此,作为替代方案,我有一个ng分支场景,它做了一些类似的事情,允许手动引导站点运行


这不是一个节点模块,因此您必须手动设置它,但最好(IMHO)有这样的东西,而不是用一些东西感染生产代码,只是为了让测试通过。

是的,这是一个好的观点。Karma创建另一个框架,包括角度场景的框架,其中包括应用程序的框架。因此,在本例中,它确实是父帧而不是顶部帧。您是否有机会提供github回购或小提琴?非常感谢Francis。请注意,如果出于任何原因将JQuery包含在runner页面中,则需要在消息事件到达时打开它,例如:if(e.originalEvent)e=e.originalEvent;