Angularjs 如何在范围变量中存储角度指令?

Angularjs 如何在范围变量中存储角度指令?,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我正在AngularJS中实现一个表单生成器,需要在运行时插入和重新排序指令。 甚至不知道从哪里开始寻找——所有的例子似乎都只演示了指令的静态树。实现动态行为的两个选项是:a)动态编译和插入模板,b)使用所有可能指令的巨大ng开关。这两种方式都是丑陋的 有人能提出更好的实施方案吗? 下面是我认为formbuilder在理想世界中的JS和html代码,请帮我填写3个TODO实例 JavaScript: angular.module('components', []) .directive('c

我正在AngularJS中实现一个表单生成器,需要在运行时插入和重新排序指令。 甚至不知道从哪里开始寻找——所有的例子似乎都只演示了指令的静态树。实现动态行为的两个选项是:a)动态编译和插入模板,b)使用所有可能指令的巨大ng开关。这两种方式都是丑陋的

有人能提出更好的实施方案吗?

下面是我认为formbuilder在理想世界中的JS和html代码,请帮我填写3个TODO实例

JavaScript:

angular.module('components', [])
  .directive('checkbox', function() {
    return {
      restrict: 'E',
      template: '<div class=f><input type=checkbox>{{name}}</input></div>'
    };
  })
  .directive('textfield', function() {
    return {
      restrict: 'E',
      template: '<div class=f><input type=text placeholder="{{name}}"></input></div>'
    };
  })

function FormBuilder($scope, $locale) {
    $scope.title = 'test form';
    $scope.fields = [];  
    $scope.add_checkbox = function() {
        console.log('adding checkbox');
        var field = null; // TODO: how do I instantiate a directive?
        $scope.fields.push(field);
    };
    $scope.add_textfield = function() {
        console.log('adding textfield');
        var field = null; // TODO: how do I instantiate a directive?
        $scope.fields.push(field);
    };
}
角度模块('组件',[]) .directive('checkbox',function(){ 返回{ 限制:'E', 模板:“{name}}” }; }) .directive('textfield',function(){ 返回{ 限制:'E', 模板:“” }; }) 函数FormBuilder($scope,$locale){ $scope.title=‘测试表格’; $scope.fields=[]; $scope.add_checkbox=函数(){ log(“添加复选框”); var field=null;//TODO:如何实例化指令? $scope.fields.push(字段); }; $scope.add_textfield=函数(){ log('addingtextfield'); var field=null;//TODO:如何实例化指令? $scope.fields.push(字段); }; } HTML:


新支票箱
新文本字段
{{title}}

我认为您有两种方法可以做到这一点,因为您不想进行切换,所以可以为每个指令创建一个模板文件。ie checkbox.html、textfield.html,并将指令放入其中。然后用
['checkbox.html','textarea.html']
填充字段数组,当您在循环中添加时,您只需

下面是一个演示:

您还可以创建另一个指令,在其中传入输入类型并将其注入模板。这是一个演示,它允许您避免声明模板,并允许指令根据字段类型创建模板:


此主字段指令只是根据字段的值编译模板

.directive('masterField', function($compile) {
   return {
      restrict: 'E',
      replace:true,
      transclude: true,
      scope:{
         type:'='
      },
      template: '<div></div>',
      controller: function ( $scope, $element, $attrs ) {},
      link: function(scope, element, attrs) {

       element.append( $compile('<' + scope.type+ '/></' +scope.type + '>')(scope) ); 
      }
    };
 })
指令('masterField',函数($compile){ 返回{ 限制:'E', 替换:正确, 是的, 范围:{ 类型:'=' }, 模板:“”, 控制器:函数($scope,$element,$attrs){}, 链接:函数(范围、元素、属性){ 元素。追加($compile(“”)(scope)); } }; })
回答得很好,谢谢你花这么多时间在上面。仍然缺少的一件事是如何将特定于字段的数据绑定到动态模板?我的意思是如果$scope.fields=[{type:'checkbox',name:'agree',selected:false},{type:'textfield',name:'email',defvalue:'foo@bar.com'}]并且我希望{{name}在模板内解析为字段的名称,而不是最上面的控制器的$scope.name。我如何实现这样的事情?我认为这是一个很好的问题,但仍然是一个单独的问题。你的指令都没有范围:你可能需要检查这个问题:嗯,这是我首先要解决的问题:)我会接受你的回答,并尝试将事情重新表述为一个新问题。没问题,这里有几个关于指令双向绑定的问题,然而,如果它像我的答案那样编译,我认为可能会有点棘手。
<div ng:repeat="field in fields">
  <master-field type='field'></master-field>
</div>
.directive('masterField', function($compile) {
   return {
      restrict: 'E',
      replace:true,
      transclude: true,
      scope:{
         type:'='
      },
      template: '<div></div>',
      controller: function ( $scope, $element, $attrs ) {},
      link: function(scope, element, attrs) {

       element.append( $compile('<' + scope.type+ '/></' +scope.type + '>')(scope) ); 
      }
    };
 })