2015-09-18 2 views
0

У меня есть проблемы с угловыми.Генерация динамической формы AngularJS

Мне нужно сгенерировать форму с использованием 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); 

Обратите внимание, что в случае текстовое поле где мой код не удается, для everyother поле сгенерировать/выбрать/поле равнину ввода текстовой и вставьте его в контейнер. В textbox case Я пытаюсь нажать новую директиву, чтобы немного убрать этот беспорядок, но FormController не распознает его как другие простые элементы.

Любые идеи о том, как я могу сделать угловое распознавание поля, созданного моей новой директивой?

Addenda

1.- ngModel работает отлично, он обновляет правильно.
2.- Обновлено JSFiddle

+0

Убрал мой ответ, потому что я думаю, что неверно истолковал ваш вопрос. Позвольте мне взглянуть поближе. –

ответ

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); 
     } 
    }; 
}]); 

делая это таким образом, я предполагаю, что ваш контроллер не нужен, но он все еще может быть. Во всяком случае, вы можете увидеть это working on plnkr.

+0

Я вижу твой трюк, тем не менее до сих пор получаю этот «TypeError: Can not read property» $ setDirty 'of undefined », поскольку он не связывается перед контроллером формы. Я делаю еще одно обходное решение с ngModelController, и это сработало, я обновляю JSFiddle через пару минут. – josegomezr

+0

Проверьте обновленный jsFiddle, я сделал прогресс, теперь он не выдает ошибок, но проверки, такие как требуемые, не работают. – josegomezr

+0

Я не на компьютере прямо сейчас (на моем мобильном телефоне), поэтому я не могу сильно помочь, но я думаю, что ваша проблема в той же директиве. Вы также должны добавить атрибуты для проверки на этот вход (другие два, похоже, работают). –

Смежные вопросы