如何在angular config inc中正确使用全局变量。测试

时间:2016-05-17 16:26:43

标签: angularjs global-variables karma-jasmine

我正在尝试为wordpress网站编写一个角度主题,我正在遵循使用functions.php来定义指向一个全局变量的常见wordpress / angular“模式”。 views / partials文件夹,以便路由可以引用它。

functions.php

wp_localize_script( 'appJs', 'localized',
    array (
        'partials' => get_stylesheet_directory_uri() . '/views'
    )
);

我的角度配置类:

function AngularConfig($routeProvider, $locationProvider) {
    $locationProvider.html5Mode(true);

    $routeProvider
        .when('/', {
            templateUrl: localized.partials + '/home.html',
            controller: 'HomeController'
        })
        .when('/projects/', {
            templateUrl: localized.partials + '/projects.html',
            controller: 'ProjectsController'
        })
        .when('/contact/', {
            templateUrl: localized.partials + '/contact.html',
            controller: 'ContactController'
        })
        .otherwise({
            redirectTo: '/'
        });
}

export default AngularConfig;

在运行时,这是有效的,因为localized是全局的,属性为partials。然而,我的测试(业力,茉莉,幻影)失败了,因为全球尚未在其环境中定义。 (另外,以这种方式直接引用全局变量是令人讨厌的,并且违背整个DI运动等)

我(想)我想把`windowProvider'注入config类,并从那里获取变量。像这样:

function AngularConfig($routeProvider, $locationProvider, $windowProvider) {
    $locationProvider.html5Mode(true);

    let partialsRoot = $windowProvider.$get().localized.partials;

    $routeProvider
        .when('/', {
            templateUrl: partialsRoot + '/home.html',
            controller: 'HomeController'
        })
        .when('/projects/', {
            templateUrl: partialsRoot + '/projects.html',
            controller: 'ProjectsController'
        })
        .when('/contact/', {
            templateUrl: partialsRoot + '/contact.html',
            controller: 'ContactController'
        })
        .otherwise({
            redirectTo: '/'
        });
}

export default AngularConfig;

但是在测试启动模块之前,我无法弄清楚如何修改window / windowProvider
我试过这个:

beforeEach(module(MODULE_NAME, function ($windowProvider) {
    let $window = $windowProvider.$get();
    $window.localized = {
        partials: 'some-path/'
    };
    console.log("WINDOW:", $window);
}));

但是,除非我没有在配置类中引用console.log,否则.localized.partials不会被执行 - 这使我认为模块(和配置)在修改函数之前被实例化window

非常感谢任何有关此的帮助或指示 感谢

1 个答案:

答案 0 :(得分:1)

$window服务的原因是它可以被存根/模拟,因此如果服务污染它,就不需要拆除真实的window

原始$window服务以任何方式引用window,以及$windowProvider.$get(),因此它们可与window互换使用。

由于Angular服务是单例,因此注入$window服务的好处是它可以在应用程序中进行模拟和使用,并引用相同的模拟对象。通常$window可以像这样嘲笑

// module order matters
module(($provide) => {
  $provide.factory('$window', () => {});
}, 'app');

当Angular DI被$windowProvider.$get()滥用时,这不是真的。当这样调用它将引用不同的对象而不是模拟$window时,除了调用它的函数范围之外,无法从任何地方访问此对象。

可以通过模拟$window来解决此问题:

beforeEach(() => {
  module({ $window: {} }, 'app');
  ...

这样

  • $windowProvider在注入app config
  • 之前被模拟
  • $windowProvider.$get$window引用相同的{}对象,因为该对象是在服务定义上创建的,并且未包含在工厂函数中
  • 每个规范都会重新发布
  • {}个对象。

但这样做的正确方法是使用constant

app.constant('localized', window.localized);

正是因为那样。通过DI去除全局常量并在配置和运行阶段使用它们。它可以像任何其他服务一样被模拟

module(($provide) => {
  $provide.constant('localized', {});
}, 'app');