【问题标题】:How to use angular-scenario with requirejs如何在 requirejs 中使用角度场景
【发布时间】:2013-03-19 12:50:13
【问题描述】:

当您的 Angular 应用程序在 DOM 上准备就绪时,Angular-scenario 运行良好。使用 requirejs 或其他 AMD 库时并非如此。如何在 angular-scenario 中添加对 AMD 的支持?

【问题讨论】:

    标签: javascript angularjs requirejs angular-scenario


    【解决方案1】:

    您需要做的是覆盖默认的帧加载行为,并在您的 amd 应用程序准备好时发出一个新事件。

    第一件事是在您的 Angular 应用程序中添加以下行以及 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 跑步者中,您必须包含这些行。如果是外部脚本,则必须在 angular-scenario 之后加载,并且必须在 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-scenario的脚本标签中。

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

    你现在准备好了

    使用 angular-scenario v1.0.3 测试

    【讨论】:

    • 你能提供一个 github repo 或 fiddle 吗?
    • 非常感谢弗朗西斯。请注意,如果出于任何原因在运行器页面中包含 JQuery,则需要在消息事件到达时对其进行解包,例如: if (e.originalEvent) e = e.originalEvent;
    【解决方案2】:

    上述答案在我的场景中部分失败(Angular 1.1.4,fresh Karma)。 在调试视图中它运行良好,在正常的概述页面中它失败了。我注意到一个额外的嵌套。

    我将代码更改为向被测应用程序的父 iframe 发送消息。

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

    【讨论】:

    • 是的,这很好。业力创建另一个框架,其中包括角度场景的框架,其中包括您的应用程序的框架。所以在这种情况下,它确实是父框架而不是顶部框架。
    【解决方案3】:

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

    因此,如果有帮助,我为 karma 创建了一个预处理器,以便在测试运行中注入“修复”。

    代码:https://github.com/tapmantwo/karma-ng-bootstrap-fix-preprocessor npm:https://www.npmjs.org/package/karma-ng-bootstrap-fix-preprocessor

    请注意,这仅在您通过 karma 提供文件时才有效。如果您要代理它们,它们不会经过预处理器。因此,作为替代方案,我有一个 ng-scenario 的分支,它执行类似的操作以允许手动引导的站点运行;

    https://github.com/tapmantwo/karma-ng-scenario

    这不是一个节点模块,所以你必须手动设置它,但最好(恕我直言)有这样的东西,而不是感染生产代码只是为了让测试通过。

    【讨论】:

      猜你喜欢
      • 2015-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-20
      • 2017-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多