简体   繁体   English

在angularjs控制器中调用全局javascript函数的可测试方法

[英]Testable method for calling global javascript functions in angularjs controllers

Very Global Description 全局描述

You have functions that must exist in the global scope. 您具有必须在全局范围内存在的功能。 You want a way to encapsulate the functionality of these functions in a dependency injectable way so they are more testable. 您需要一种以可依赖注入的方式封装这些功能的功能的方法,以便对其进行测试。 What is the correct way to do this? 正确的方法是什么?

Somewhat Specific Description 有点具体的描述

I have a situation where I have an existing javascript library that uses a lot of variables and function in the global scope. 我遇到的情况是,我有一个现有的JavaScript库,该库在全局范围内使用很多变量和函数。 The library is a SCORM engine and part of the standard dictates that the functions must be available in the global scope (so user created content can access them). 该库是SCORM引擎,该标准的一部分规定这些功能必须在全局范围内可用(以便用户创建的内容可以访问它们)。

However, there are a couple of places in various controllers that I must call them as well. 但是,在各种控制器中有两个地方也必须称为它们。 At the moment I an just calling them, but this makes testing those lines difficult and seems to violate the angular mindset in general. 目前,我只是打电话给他们,但这使测试这些行变得困难,并且似乎违反了一般的角度观念。

Plnkr Plnkr

A plunk just illustrating how things are now 只是说明现在的情况

var globalVariable = 1;

function globalFunction(){
  return "cats";
}

var app = angular.module('plunker', []);

app.controller('MainCtrl', [ '$scope', function($scope) {
  $scope.name = 'World';
  $scope.cats = globalFunction(); //This line is hard to test and makes me feel dirty.
}]);

A plunk that wraps the function in a factory (maybe what is recommended in comments?) 一个将函数包装在工厂中的插件(也许在注释中推荐了什么?)

var globalVariable = 1;

function globalFunction(){
  return "cats";
}

var app = angular.module('plunker', []);

app.factory('angularFriendly', function(){
  this.globalFunction = globalFunction;
  return this;
});

app.controller('MainCtrl', ['$scope', 'angularFriendly',
  function($scope, angularFriendly) {
    $scope.name = 'World';
    $scope.cats = angularFriendly.globalFunction();
  }
]);

This is more or less what I mean in my original comment when I said I considered wrapping it in a service. 当我说我考虑将其包装在服务中时,这或多或少是我在原始评论中的意思。 I make the function injectable (which is good and is much more testable) but I am not sure it is good practice (because I have just moved the difficult to test code to a different place). 我将函数设为可注入的(这很好,并且可测试性更高),但是我不确定这是一个好习惯(因为我刚刚将难以测试的代码移到了其他位置)。

I prefer wrapping 3rd party non-Angular applications into value objects (which is functionally the same as using a factory and immediately calling it prior to injection, which feels cleaner). 我更喜欢将第三方非Angular应用程序包装到值对象中(这在功能上与使用工厂相同,并在注入之前立即调用它,这感觉更干净)。

var globalVariable = 1;

function globalFunction(){
  return "cats";
}

var app = angular.module('plunker', []);
app.value('external', globalFunction);

app.controller('MainCtrl', ['$scope', 'external',
  function($scope, external) {
    $scope.name = 'World';
    $scope.cats = external();  // Treat the dependency as a service to resolve into the scope
  }
]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM