我正在创建一个templateparser,它可以解析多个模板并返回生成的html内容。为了绑定html和视图信息,我使用的是Angular $compile
服务。我遇到的问题是在解决promise之前调用了promise .then()(因此导致了undefined
)。
AngularJS版本:1.6.3
解析器功能
/**
* Using the $compile function, this function generates a full HTML page based on the given process and template
* It does this by binding the given process to the template $scope and uses $compile to generate a HTML page
* @param {Afhandeling} process - The process that can bind to the template
* @param {string} templatePath - The location of the template that should be used
* @param {boolean} [useCtrlCall=true] - Whether or not the process should be a sub part of a $ctrl object. If the template is used
* for more then only an email template this could be the case (EXAMPLE: $ctrl.<process name>.timestamp)
* @return {IPromise<string>} A full HTML page
*/
public createEmail(process: Afhandeling, templatePath: string, useCtrlCall = true): ng.IPromise<string> {
let processScope = {};
if (useCtrlCall) { //Create scope object | Most templates are called with $ctrl.<process name>
const controller = "$ctrl";
processScope[controller] = {};
processScope[controller][process.__className.toLowerCase()] = process;
} else {
processScope = process;
}
return this.$http.get(templatePath)
.then((response) => {
let template = response.data;
let scope = this.$rootScope.$new();
angular.extend(scope, processScope);
let generatedTemplate = this.$compile(jQuery(template))(scope);
let waitForRenderCompletion = () => {
if (scope.$$phase || this.$http.pendingRequests.length) {
console.warn("Time for a timeout.");
this.$timeout(waitForRenderCompletion);
} else {
console.warn("Lets return the template.");
return generatedTemplate[0].innerHTML;
}
};
waitForRenderCompletion();
})
.catch((exception) => {
console.error(exception);
this.logger.error(
TemplateParser.getOnderdeel(process),
"Email template creation",
(<Error>exception).message
);
return null;
});
}
函数调用
this.templateParser.createEmail(
this.model,
"<template url>"
).then((template: string) => {
console.warn(template); //Results in 'undefined'
});
我正在查看$$phase
更改的原因是$compile
没有就编译完成时提供任何反馈。模板可以由ng-include
组合在一起的不确定数量的模板组成。 ng-includes也是异步,因此我无法想到检查$compile
何时完成(My question about a better solution then this)的任何其他方法。
我在想什么
当我查看控制台输出时,我得到以下内容:
Time for a timeout.
undefined
(2) Time for a timeout.
Lets return the template.
因此,当第一个$timeout
结算时,似乎会自动解决承诺。然而,这没有任何意义,因为我没有返回任何东西。
感谢任何帮助。
答案
感谢@charlietfl的提示。工作代码如下。我现在正在返回该函数,因此我的承诺中有一个返回值。我也返回$timeout
,以便可以递归调用该函数。
代码:
let waitForRenderCompletion = () => {
if (scope.$$phase || this.$http.pendingRequests.length) {
console.warn("Time for a timeout.");
return this.$timeout(waitForRenderCompletion);
});
} else {
console.warn("Lets return the template.");
return generatedTemplate[0].innerHTML;
}
};
return waitForRenderCompletion();