我正在尝试通过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);
}
}
};
}
};
});