0

我在角度方面遇到了一些麻烦。

我需要使用由外部系统构建的 JSON Spec 生成表单(来源是可信赖的)。

首先我遇到了 FormController 的问题,因为它没有检测到我通过指令生成的元素,然后我通过将表单和字段同时生成到指令中来解决问题 问题是它像你一样非常混乱可以在这个JSFiddle中看到。

var $form = $('<form/>', {
    name: formName,
    id: formName,
    novalidate: true,
    "ng-submit": 'daForm.validate($event, ' + formName + ')'
});

var idx = 1;

for (var fieldName in spec.fieldset) {
    var $wrapper = $('<div/>', {
        id: fieldName + '-col'
    }).addClass('col-xs-12 col-md-6').appendTo($form);

    var $formGroup = $('<div/>', {
        id: fieldName + '-group'
    }).addClass('form-group').appendTo($wrapper)

    $('<label/>', {
        'for': fieldName,
        id: fieldName + '-label'
    }).addClass('control-label').text("{{'" + fieldName + "' }}").appendTo($formGroup);

    var fieldSpec = spec.fieldset[fieldName];
    var control;

    switch (fieldSpec.control) {
        case 'passwordbox':
            control = 'input';
            fieldSpec.attrs.type = "password"
            break;
        case 'number':
            control = 'input';
            fieldSpec.attrs.type = "numberbox"
            break;
        case 'email':
            control = 'input';
            control = 'input';
            fieldSpec.attrs.type = "emailbox"
            break;
        case 'select':
            control = 'select';
            break;
        case 'textarea':
            control = 'multitextbox';
            break;
        case 'textbox':
            $('<da-textbox/>').attr('defined-by', fieldName).appendTo($formGroup)
            continue;
            break;
        default:
            control = 'input';
            fieldSpec.attrs.type = "text"
            break;
    }

    var $control = $('<' + control + '/>', fieldSpec.attrs).attr('ng-model', 'model.' + fieldName).addClass('form-control').appendTo($formGroup);

    for (var rule in fieldSpec.validation) {
        $control.attr(rule, fieldSpec.validation[rule])
    }

    if (control == 'select') {
        for (var val in fieldSpec.options) {
            $('<option/>').val(val).text(fieldSpec.options[val]).appendTo($control);
        }
    }

    if (idx % 2 == 0)
        $wrapper.parent().append($('<div/>').addClass('clearfix'))
    idx++;
}

$form.append($('<div/>').addClass('clearfix'))

var $lastRow = $('<div/>').addClass('col-xs-12 col-md-12').appendTo($form);
var $submit = $('<button/>').attr('type', 'submit').addClass('btn btn-primary').appendTo(
$lastRow).text('Submit')

$form.append($('<div/>').addClass('clearfix'))
console.log(scope)

$compile($form)(scope);

element.append($form);

请注意,案例文本框是我的代码失败的地方,对于每个其他字段,我生成一个普通的输入/选择/文本区域字段并将其推送到容器。在文本框的情况下,我尝试推送一个新指令以稍微整理一下这个混乱,但 FormController 不会将其识别为其他普通项目。

关于如何让角度识别新指令生成的字段的任何想法?

附加物

1.- ngModel 工作正常,它更新正确。
2.- 更新JSFiddle

4

1 回答 1

0

好的,我知道了。您正在混合使用 jQuery 和 AngularJS,这通常会导致一些不稳定,所以我花了一分钟才知道发生了什么。所以,我是对的,daTextbox 元素没有被绑定到 $scope (你可以通过查看类列表来判断,如果它不包含 .ng-scope,则有问题)。

无论如何,首先要确保 daTextbox 将比 ngModel 更早编译(因此任何大于 0 的优先级,我选择了 1000)。然后,与其使用 jQuery 创建输入,不如使用angular.element更容易、更高效。

您要做的是创建输入,编译它,然后将其附加到您的指令元素。这是一个工作示例:

app.directive('daTextbox', ['$compile', function($compile) {
    return {
       restrict: 'E',
       scope: true,
       priority: 1000,
        controller: function($scope, $attrs) {
            this.identifier = $attrs.definedBy
            this.definition = $scope.spec.fieldset[this.identifier]
        },
        link: function(scope, element, attrs, controller) {
            var input = angular.element('<input/>')
                .addClass('form-control')
                .attr('ng-model', 'model.' + attrs.definedBy);

            input = $compile(input)(scope);
            element.append(input);
        }
    };
}]);

这样做,我猜你的控制器不是必需的,但它可能仍然是。无论如何,您可以看到这是在 plnkr 上工作的

于 2015-09-18T21:19:21.890 回答