Reputation: 150
I am trying to create a data-driven questionnaire in Angular. The questionnaire can support several types of questions which should be displayed differently based on their type. Currently, I achieve this using a series of ngIfs like so:
<div ng-if="question.type === 'SingleAnswerQuestion'">
<pn-single-answer-question model="question"></pn-single-answer-question>
</div>
<div ng-if="question.type === 'MultipleAnswerQuestion'">
<pn-multiple-answer-question model="question"></pn-multiple-answer-question>
</div>
<div ng-if="question.type === 'IncrementalSingleAnswerQuestion'">
<pn-single-answer-incremental-question model="question"></pn-single-answer-incremental-question>
</div>
This feels a little clunky to me, especially since we are going to be adding a ton more question types in the near future. So I was playing around with encapsulating this in a directive hoping that would be a little more sleek rather than trying to achieve this in a template. Here's what I came up with:
angular.module('membercenter.riskquestionnaire')
.directive('pnDynamicQuestion', function ($compile) {
return {
restrict: 'E',
scope: {
question: "=model"
},
link: function(scope, element, attrs) {
var question = scope.question;
var questionHtml = null;
if (question.type === 'SingleAnswerQuestion') {
questionHtml = '<pn-single-answer-question model="question"></pn-single-answer-question>';
} else if (question.type === 'MultipleAnswerQuestion') {
questionHtml = '<pn-multiple-answer-question model="question"></pn-multiple-answer-question>';
} else if (question.type === 'NumericSingleAnswerQuestion') {
questionHtml = '<pn-single-answer-incremental-question model="question"></pn-single-answer-incremental-question>';
}
if (questionHtml) {
var questionElement = angular.element(questionHtml);
var compiled = $compile(questionHtml);
element.append(questionElement);
compiled(scope);
}
}
};
});
This seems to work in that it correctly adds the appropriate HTML for the desired specific question type. However, the specific question type directives don't seem to actually compile, therefore nothing is displayed in the browser. Any advice?
Upvotes: 1
Views: 118
Reputation: 150
Thanks to @charlietfl for pointing out my mistake. I have corrected the last part of my code as follows:
if (questionHtml) {
var link = $compile(questionHtml);
var compiled = link(scope);
element.append(compiled);
}
Upvotes: 0
Reputation: 66
If you are looking for data-driven forms, have a look at formly: http://formly-js.github.io/angular-formly/#/
The maintainer of the project talks about solving a similar problem in this video: https://www.youtube.com/watch?v=o90TMDL3OYc
Upvotes: 2