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
if (field) {
formService.createFieldElement(field.type, $scope)
.then(function fieldElementCreated(element) {
fieldContent.append(element);
});
formService.insertFieldElement(fieldContent[0],
field.type, $scope);
}
});

View File

@@ -201,6 +201,10 @@ angular.module('form').provider('formService', function formServiceProvider() {
* model:
* 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
* The name of the field type defining the nature of the element to be
* created.
@@ -212,43 +216,51 @@ angular.module('form').provider('formService', function formServiceProvider() {
* A Promise which resolves to the compiled Element. If an error occurs
* 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
var fieldType = provider.fieldTypes[fieldTypeName];
if (!fieldType)
return $q.reject();
// Populate scope using defined controller
if (fieldType.module && fieldType.controller) {
var $controller = angular.injector(['ng', fieldType.module]).get('$controller');
$controller(fieldType.controller, {'$scope' : scope});
var templateRequest;
// Use raw HTML template if provided
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
var compiledTemplate = $q.defer();
// Use raw HTML template if provided
if (fieldType.template)
compiledTemplate.resolve($compile(fieldType.template)(scope));
// Resolve with compiled HTML upon success
templateRequest.then(function templateRetrieved(html) {
// If no raw HTML template is provided, retrieve template from URL
else {
// Insert template into DOM
fieldContainer.innerHTML = html;
// Attempt to retrieve template HTML
$templateRequest(fieldType.templateUrl)
// Populate scope using defined controller
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
.then(function templateRetrieved(html) {
compiledTemplate.resolve($compile(html)(scope));
})
// Compile DOM with populated scope
compiledTemplate.resolve($compile(fieldContainer.childNodes)(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 compiledTemplate.promise;