GUACAMOLE-136: Ensure field template is in DOM prior to invoking controller.

This commit is contained in:
Michael Jumper
2016-12-01 00:52:57 -08:00
parent 32e5c3e680
commit 6eda36cd4e
2 changed files with 35 additions and 25 deletions

View File

@@ -104,10 +104,8 @@ angular.module('form').directive('guacFormField', [function formField() {
// Append field content // Append field content
if (field) { if (field) {
formService.createFieldElement(field.type, $scope) formService.insertFieldElement(fieldContent[0],
.then(function fieldElementCreated(element) { field.type, $scope);
fieldContent.append(element);
});
} }
}); });

View File

@@ -201,6 +201,10 @@ angular.module('form').provider('formService', function formServiceProvider() {
* model: * model:
* The current String value of the field, if any. * The current String value of the field, if any.
* *
* @param {Element} fieldContainer
* The DOM Element whose contents should be replaced with the
* compiled field template.
*
* @param {String} fieldTypeName * @param {String} fieldTypeName
* The name of the field type defining the nature of the element to be * The name of the field type defining the nature of the element to be
* created. * created.
@@ -212,43 +216,51 @@ angular.module('form').provider('formService', function formServiceProvider() {
* A Promise which resolves to the compiled Element. If an error occurs * A Promise which resolves to the compiled Element. If an error occurs
* while retrieving the field type, this Promise will be rejected. * while retrieving the field type, this Promise will be rejected.
*/ */
service.createFieldElement = function createFieldElement(fieldTypeName, scope) { service.insertFieldElement = function insertFieldElement(fieldContainer,
fieldTypeName, scope) {
// Ensure field type is defined // Ensure field type is defined
var fieldType = provider.fieldTypes[fieldTypeName]; var fieldType = provider.fieldTypes[fieldTypeName];
if (!fieldType) if (!fieldType)
return $q.reject(); return $q.reject();
// Populate scope using defined controller var templateRequest;
if (fieldType.module && fieldType.controller) {
var $controller = angular.injector(['ng', fieldType.module]).get('$controller'); // Use raw HTML template if provided
$controller(fieldType.controller, {'$scope' : scope}); if (fieldType.template) {
var deferredTemplate = $q.defer();
deferredTemplate.resolve(fieldType.template);
templateRequest = deferredTemplate.promise;
} }
// If no raw HTML template is provided, retrieve template from URL
else
templateRequest = $templateRequest(fieldType.templateUrl);
// Defer compilation of template pending successful retrieval // Defer compilation of template pending successful retrieval
var compiledTemplate = $q.defer(); var compiledTemplate = $q.defer();
// Use raw HTML template if provided // Resolve with compiled HTML upon success
if (fieldType.template) templateRequest.then(function templateRetrieved(html) {
compiledTemplate.resolve($compile(fieldType.template)(scope));
// If no raw HTML template is provided, retrieve template from URL // Insert template into DOM
else { fieldContainer.innerHTML = html;
// Attempt to retrieve template HTML // Populate scope using defined controller
$templateRequest(fieldType.templateUrl) if (fieldType.module && fieldType.controller) {
var $controller = angular.injector(['ng', fieldType.module]).get('$controller');
$controller(fieldType.controller, {'$scope' : scope});
}
// Resolve with compiled HTML upon success // Compile DOM with populated scope
.then(function templateRetrieved(html) { compiledTemplate.resolve($compile(fieldContainer.childNodes)(scope));
compiledTemplate.resolve($compile(html)(scope));
})
// Reject on failure })
['catch'](function templateError() {
compiledTemplate.reject();
});
} // Reject on failure
['catch'](function templateError() {
compiledTemplate.reject();
});
// Return promise which resolves to the compiled template // Return promise which resolves to the compiled template
return compiledTemplate.promise; return compiledTemplate.promise;