创建一个操作DOM的指令,以添加依赖于范围的子指令

时间:2015-03-10 14:19:33

标签: javascript angularjs angularjs-directive

我正在尝试在Angular中创建一个数据驱动的调查问卷。问卷可以支持几种类型的问题,这些问题应根据其类型进行不同的显示。目前,我使用一系列ngIfs来实现这一点:

<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>

这对我来说有点笨拙,特别是因为我们将在不久的将来增加更多问题类型。所以我正在玩这个在一个指令中封装它,希望它会更加光滑,而不是试图在模板中实现这一点。这就是我想出的:

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);
      }
    }
  };
});

这似乎有效,因为它正确地为所需的特定问题类型添加了适当的HTML。但是,具体的问题类型指令似乎并没有实际编译,因此浏览器中不会显示任何内容。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

如果您正在寻找数据驱动的表单,请查看一下:http://formly-js.github.io/angular-formly/#/

该项目的维护者讨论了解决此视频中的类似问题:https://www.youtube.com/watch?v=o90TMDL3OYc

答案 1 :(得分:0)

感谢@charlietfl指出我的错误。我已经更正了我的代码的最后一部分如下:

if (questionHtml) {
  var link = $compile(questionHtml);
  var compiled = link(scope);
  element.append(compiled);
}