angularjs,动态和递归构建形式来自json与嵌套指令

时间:2016-04-13 10:31:10

标签: javascript angularjs json forms angularjs-directive

我正在尝试通过websocket从JSON中构建动态表单。

因此,我试图嵌套两个指令,一个用于表单本身(newForm),另一个用于表单项(formItems),它们应该从JSON递归生成(使用RecursionHelper)。

最后,我想在模糊或提交时发送表单对象。我试图动态传递表单的名称,

<form name='panelitems.html_form'>   or
<form name='{{panelitems.html_form}}'>

但我无法使用任一指令中的链接表单项访问表单对象。我想将表单数据提交回websocket,例如用于验证。

有没有人有想法,我在这里弄乱了什么或知道更好的方法吗?非常感谢你们。

我在小提琴上建立了一个例子:http://jsfiddle.net/3or3p2ba/

HTML:

 <div ng-controller="FormCtrl">
   <new-form panelitems='json[0]'></new-form>
 </div>

JS:

 var myApp = angular.module('myApp', []);

 myApp.directive('newForm', function(RecursionHelper) {
   return {
     restrict: "E",
     replace: true,
     scope: {
       panelitems: '='
     },
     template: 
       "<form name='{{panelitems.html_form}}'> " +
       "<form-items parentform='panelitems.html_form' items='panelitems'></form-items>" +
       "<br><br>" +
       "<pre>{{panelitems.html_form}} = {{ panelitems.html_form | json}}</pre><br>" +
       "</form>",
     compile: function(element) {
       return RecursionHelper.compile(element, function(scope, iElement, iAttrs, controller, transcludeFn) {});
     },
     controller: function($scope) {
       $scope.submit = function(form) {
         alert("newForm - submit - " + JSON.stringify(form));
       };

       $scope.redirect = function(destination) {
         alert("newForm - redirect - " + destination);
       };

       $scope.check = function(input) {
         alert("newForm - check - " + input);
       };

     }
   };
 });

 myApp.directive('formItems', function(RecursionHelper) {
   return {
     restrict: "E",
     replace: true,
     scope: {
       items: '=',
       parentform: '='
     },
     template: '<div ng-repeat="item in items.children">' +
       '<form-items parentform="parentform" items="item"></form-items>' +

       '<div ng-if="item.item_type == ' + "'input'" + '">' +
       '<input name={{item.item_key}} ng-blur="check(parentform)" type={{item.input_type}} placeholder={{item.item_name}} title={{item.item_tooltip}}>' +
       '</div>' +

       '<div ng-if="item.item_type == ' + "'button'" + '">' +
       '<button ng-click=submit(parentform) class="btn btn-default btn-block">{{item.item_infotext}}</button>' +
       '</div>' +
       '</div>'
   };
 });

 myApp.controller('FormCtrl', function($scope) {
   $scope.json = [{
     "html_form": "signup_panel",
     "item_type": "itemgroup",
     "children": [{
       "item_type": "itemgroup",
       "children": [{
         "item_type": "itemgroup",
         "children": [{
           "item_name": "First name",
           "item_required": "true",
           "item_key": "input1",
           "item_type": "input",
           "input_type": "text",
           "item_of": "signup_panel"
         }, {
           "item_name": "Last name",
           "item_required": "true",
           "item_key": "input2",
           "item_type": "input",
           "input_type": "text",
           "item_of": "signup_panel"
         }]
       }, {
         "item_tooltip": "Please provide your email address.",
         "item_name": "Email",
         "item_required": "true",
         "item_key": "input5",
         "item_of": "signup_panel",
         "item_type": "input",
         "input_type": "email"
       }, {
         "item_tooltip": "Please re-enter your email address for validation purposes.",
         "item_name": "Re-enter email",
         "item_required": "true",
         "item_key": "input6",
         "item_of": "signup_panel",
         "item_type": "input",
         "input_type": "email"
       }, {
         "item_tooltip": "Please enter a password you want to use.",
         "item_name": "New password",
         "item_required": "true",
         "item_key": "input7",
         "item_of": "signup_panel",
         "item_type": "input",
         "input_type": "passwort"
       }, {
         "item_infotext": "Sign Up",
         "item_of": "signup_panel",
         "item_type": "button",
         "input_type": "click"
       }]
     }]
   }];
 });

 myApp.factory('RecursionHelper', function($compile) {
   return {
     /**
      * Manually compiles the element, fixing the recursion loop.
      * @param element
      * @param [link] A post-link function, or an object with function(s) registered via pre and post properties.
      * @returns An object containing the linking functions.
      */
     compile: function(element, link) {
       // Normalize the link parameter
       if (angular.isFunction(link)) {
         link = {
           post: link
         };
       }

       // Break the recursion loop by removing the contents
       var contents = element.contents().remove();
       var compiledContents;
       return {
         pre: (link && link.pre) ? link.pre : null,
         /**
          * Compiles and re-adds the contents
          */
         post: function(scope, element) {
           // Compile the contents
           if (!compiledContents) {
             compiledContents = $compile(contents);
           }
           // Re-add the compiled contents to the element
           compiledContents(scope, function(clone) {
             element.append(clone);
           });

           // Call the post-linking function, if any
           if (link && link.post) {
             link.post.apply(null, arguments);
           }
         }
       };
     }
   };
 });

0 个答案:

没有答案