使用angularJS动态生成表单的问题

时间:2014-07-17 16:05:23

标签: angularjs input angularjs-ng-repeat dynamically-generated ng-repeat

我正在尝试使用angularJS动态生成表单。 通常这很好用但是这个表单有动态类型,有些应该是文本,电子邮件,重要的是密码。 真的,我希望它适用于所有事情,但密码是最重要的。

目前我的代码是

<input ng-repeat="input in credForm.loginForm.fields" type="{{input.fieldType}}"
ng-model="credForm.loginForm.fields[$index].value" ng-model-options="{ updateOn:
'blur' }" placeholder="{{input.fieldName}}..." ng-required="!input.optional">

关于这一切的一切都很棒,但是类型不起作用我得到错误“错误:类型属性无法更改”这显然是一个安全问题。我们如何通过在javascript中生成元素并将其添加为具有ID的子项,而不必做任何令人厌恶的事情来解决这个问题。

1 个答案:

答案 0 :(得分:0)

以下是我在使用的指令中处理的方法 - 请注意链接功能底部的编译。在您的情况下,您可能只需要一个针对该类型的指令 - 因此您可以继续使用现有代码 - 例如field-type="{{input.fieldType}}",然后只需使用element.find("input").attr("type", attrs.fieldType),然后使用编译。

  angular.module("schemaForm").directive("schemaFormField", 
    ['$compile', '$templateCache', '$dialog', '$q', 
    function ($compile, $templateCache, $dialog, $q) {
        return {
            restrict: "EA",
            replace: true,
            require: "^form",
            scope: { 
                schema: "=",
                model: "=",
                field: "=",
                required: "=",
                onClick: "@",
                editAs: "@"
            },
            link: function (scope, element, attrs, formController) {
                var template;
                var searchBox = $templateCache.get("searchBox.html");

                scope.formState = formController; // form state checking (pristine, etc.)

                scope.opts = {
                    backdrop: true,
                    keyboard: true,
                    backdropClick: true,
                    template: searchBox, 
                    //templateUrl: 'schemaFormSearchBox.html',
                    controller: 'schemaFormSearchCtrl'
                };

                // enables ng-show of label                
                scope.isEmpty = function() { 
                  return typeof scope.model[scope.field] === 'undefined';
                };

                // launches search dialog on ng-click
                scope.search = function() {
                  scope.opts.item = scope.schema;
                  var d = $dialog.dialog(scope.opts);
                  d.open().then(function (result) {
                    if (result) { // don't overwrite if cancelled
                      scope.model[scope.field] = result;
                    }
                  });
                };

                // perhaps throw exeception instead?
                if (scope.schema === undefined) {
                  return $compile(element.contents())(scope);
                }

                // assigned template according to form field type
                template = (scope.schema["enum"] !== undefined) && 
                           (scope.schema["enum"] !== null) ? 
                           $templateCache.get("enumField.html") : 
                           $templateCache.get("" + scope.schema.type + "Field.html");
                element.html(template);

                // update attributes - type, ng-required, ng-pattern, name
                if (scope.schema.type === "number" || scope.schema.type === "integer") {
                    element.find("input").attr("type", "number");
                }
                element.find("input").attr("ng-required", scope.required);
                if (scope.schema.pattern) {
                    element.find("input").attr("ng-pattern", "/" + scope.schema.pattern + "/");
                }
                element.find("input").attr("name", scope.field);

                // compile template against current scope
                return $compile(element.contents())(scope);
            }
        };
    }]);
})