0

角度に問題があります。

外部システムによって構築された JSON 仕様を使用してフォームを生成する必要があります (ソースは信頼できます)。

最初に 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 はそれを他のプレーンなアイテムとして認識しません。

新しいディレクティブによって生成されたフィールドをAngularに認識させる方法についてのアイデアはありますか?

補遺

1.- ngModel は正常に動作し、正しく更新されます。
2.-更新されたJSFiddle

4

1 に答える 1

0

はい、わかった。jQuery と AngularJS を混在させているため、しばしば不安定になるため、何が起こっているのかを理解するのに 1 分かかりました。だから、私は正しかった、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 に答える