如何将 angular 指令存储在范围变量中? [英] How do I store angular directive in a scope variable?

查看:25
本文介绍了如何将 angular 指令存储在范围变量中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

谁能提出更好的实施方案?

下面是 JS 和 html 代码,我认为 formbuilder 在理想世界中应该是什么样子,请帮我填写 3 个 TODO 实例.

JSFiddle JavaScript:

angular.module('components', []).directive('checkbox', function() {返回 {限制:'E',模板:'<div class=f><input type=checkbox>{{name}}</input></div>'};}).directive('textfield', function() {返回 {限制:'E',模板:'<div class=f><input type=text placeholder="{{name}}"></input></div>'};})函数 FormBuilder($scope, $locale) {$scope.title = '测试表';$scope.fields = [];$scope.add_checkbox = function() {console.log('添加复选框');var 字段 = null;//TODO:如何实例化指令?$scope.fields.push(field);};$scope.add_textfield = function() {console.log('添加文本框');var 字段 = null;//TODO:如何实例化指令?$scope.fields.push(field);};}

HTML:

<button ng:click="add_checkbox()">新的复选框</button><button ng:click="add_textfield()">新文本字段</button><h3>{{title}}</h3><复选框></复选框><文本域></文本域><div ng:repeat="字段中的字段"><!-- TODO field.get_html() - 如何?-->

解决方案

我认为您有几种方法可以做到这一点,因为您不想进行切换,因此可以为每个指令创建一个模板文件.即 checkbox.html、textfield.html 并将指令放在每一个中.然后用 ['checkbox.html', 'textarea.html'] 填充你的 fields 数组,当你在循环中添加时,你只需 <div ng-include='field'>

这是一个演示:http://plnkr.co/edit/w6n6xpng6rP5WJHDlJ3Y?p=preview

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

http://plnkr.co/jhWGuMXZTuSpz8otsVRY

<master-field type='field'></master-field>

这个主字段指令只是根据字段的值编译一个模板.

.directive('masterField', function($compile) {返回 {限制:'E',替换:真,转置:真实,范围:{类型:'='},模板:'<div></div>',控制器:函数 ( $scope, $element, $attrs ) {},链接:函数(范围,元素,属性){element.append( $compile('<' + scope.type+ '/></' +scope.type + '>')(scope));}};})

I am implementing a form builder in AngularJS and need to insert and reorder directives at runtime. Don't even know where to start looking - all examples seem to only demonstrate static tree of directives. Two options to achieve dynamic behaviour are: a) compiling and inserting templates on the fly and b) using huge ng-switch of all possible directives. Both ways are ugly.

Can anyone suggest a better implementation?

Below is JS and html code for how I think formbuilder should look in an ideal world, please help me fill in 3 instances of TODO.

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

HTML:

<div ng-app=components ng-controller=FormBuilder>
    <button ng:click="add_checkbox()">new checbox</button>
    <button ng:click="add_textfield()">new text field</button>
    <h3>{{ title }}</h3>
    <checkbox></checkbox>

    <textfield></textfield>

    <div ng:repeat="field in fields">
        <!-- TODO field.get_html() - how? -->
    </div>
</div>

解决方案

I think you have a couple ways to do this as you mentioned and since you don't want to do a switch you can create a template file for each directive. ie checkbox.html, textfield.html and put the directive in each one. Then populate your fields array with ['checkbox.html', 'textarea.html'] when you add in your loop you just simply <div ng-include='field'></div>

Here is a demo: http://plnkr.co/edit/w6n6xpng6rP5WJHDlJ3Y?p=preview

You could also create another directive where you pass in the input type and have it inject it into the template. Here is a demo of this which allows you to avoid having to declare templates and letting a directive create them based on the field type:

http://plnkr.co/jhWGuMXZTuSpz8otsVRY

<div ng:repeat="field in fields">
  <master-field type='field'></master-field>
</div>

This master-field directive just compiles a template based on the value of field.

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

这篇关于如何将 angular 指令存储在范围变量中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆