GUACAMOLE-630: Create a new injector for field type instances only if needed.

Creating a new injector re-initializes services and providers within
its modules. If those services or providers rely on being singletons
(as colorPickerService does), this produces unexpected behavior.
This commit is contained in:
Michael Jumper
2019-08-18 22:00:16 -07:00
parent 83f1849215
commit 93ba19ac26

View File

@@ -220,10 +220,45 @@ angular.module('form').provider('formService', function formServiceProvider() {
var $q = $injector.get('$q'); var $q = $injector.get('$q');
var $templateRequest = $injector.get('$templateRequest'); var $templateRequest = $injector.get('$templateRequest');
/**
* Map of module name to the injector instance created for that module.
*
* @type {Object.<String, injector>}
*/
var injectors = {};
var service = {}; var service = {};
service.fieldTypes = provider.fieldTypes; service.fieldTypes = provider.fieldTypes;
/**
* Given the name of a module, returns an injector instance which
* injects dependencies within that module. A new injector may be
* created and initialized if no such injector has yet been requested.
* If the injector available to formService already includes the
* requested module, that injector will simply be returned.
*
* @param {String} module
* The name of the module to produce an injector for.
*
* @returns {injector}
* An injector instance which injects dependencies for the given
* module.
*/
var getInjector = function getInjector(module) {
// Use the formService's injector if possible
if ($injector.modules[module])
return $injector;
// If the formService's injector does not include the requested
// module, create the necessary injector, reusing that injector for
// future calls
injectors[module] = injectors[module] || angular.injector(['ng', module]);
return injectors[module];
};
/** /**
* Compiles and links the field associated with the given name to the given * Compiles and links the field associated with the given name to the given
* scope, producing a distinct and independent DOM Element which functions * scope, producing a distinct and independent DOM Element which functions
@@ -300,7 +335,7 @@ angular.module('form').provider('formService', function formServiceProvider() {
// Populate scope using defined controller // Populate scope using defined controller
if (fieldType.module && fieldType.controller) { if (fieldType.module && fieldType.controller) {
var $controller = angular.injector(['ng', fieldType.module]).get('$controller'); var $controller = getInjector(fieldType.module).get('$controller');
$controller(fieldType.controller, { $controller(fieldType.controller, {
'$scope' : scope, '$scope' : scope,
'$element' : angular.element(fieldContainer.childNodes) '$element' : angular.element(fieldContainer.childNodes)