it-swarm.com.ru

Атрибут имени динамической формы <input type = "text" name = "{{variable-name}}" /> в Angularjs

Как кто-то может использовать formName.inputName. $ Valid, когда «inputName» было создано динамически?

  <form name="formName">
    <input ng-repeat="(variable) in variables"
           type="text" name="variable.name"
           ng-model="variable.name" required />
 </form>

Выводом входного атрибута HTML «name» будет строка «variablename», которая будет применяться ко ВСЕМ повторным вводам.

Если бы мы попробовали это

<form name="formName">
  <input ng-repeat="(variable) in variables"
         type="text" name="{{ variable.name }}"
         ng-model="variable.name" required />
</form>

Вывод входного атрибута HTML «name» будет строкой «{{variable.name}}», которая будет применяться ко ВСЕМ повторным вводам.

В любом из этих двух условий атрибут имени для каждого из повторяющихся элементов ввода не будет создаваться динамически; ВСЕ входы будут иметь одинаковое имя входа. Не очень хорошо, если вы хотите вызвать конкретный вход на основе конкретного имени.

  • нужно использовать динамические значения имени
  • нужно иметь возможность вызывать $ scope.formName.dynamicName. $ valid
  • нужно иметь возможность вызывать $ scope.formName. $ valid
  • нужны динамические поля ввода имени для добавления во вложенную форму или в основную форму
23
SoEzPz

Я не мог найти ответ, который удовлетворил бы некоторые или все эти потребности. Это то, что я придумал. 

Там может быть лучший способ, поэтому, пожалуйста, поделитесь своими мыслями.
Я использую Angularjs 1.3.0-beta.8

У меня есть форма с несколькими вложенными директивами, которые содержат вход (ы), select (s) и т.д. .... Все эти элементы заключены в ng-повторы и динамические строковые значения.

Вот как использовать директиву:

<form name="myFormName">
  <nested directives of many levels>
    ex: <input ng-repeat=(index, variable) in variables" type="text"
               my-name="{{ variable.name + '/' + 'myFormName' }}"
               ng-model="variable.name" required />
    ex: <select ng-model="variable.name" ng-options="label in label in {{ variable.options }}"
                my-name="{{ variable.name + '/' + 'myFormName' }}"
        </select>
</form>

Примечание: вы можете добавлять и индексировать конкатенацию строк, если вам нужно сериализовать, возможно, таблицу входов; что я и сделал Однако динамический ввод имени означает, что вы можете не знать имя ввода формы, поэтому как бы вы назвали $ scope.formName. ??????. Вы можете перебрать объект $ scope.formName, чтобы получить ключи, которые соответствуют определенному значению. Это означает конкатенацию строк следующим образом:

my-name="{{ dynamicString + hello + '/' + 'myFormName' }}"

Затем в $ scope.myFormName вы найдете любое входное имя формы, просто перебирая объект и собирая все ключи, которые включают 'hello'.

app.directive('myName', function(){

  var myNameError = "myName directive error: "

  return {
    restrict:'A', // Declares an Attributes Directive.
    require: 'ngModel', // ngModelController.

    link: function( scope, elem, attrs, ngModel ){
      if( !ngModel ){ return } // no ngModel exists for this element

      // check myName input for proper formatting ex. something/something
      checkInputFormat(attrs);

      var inputName = attrs.myName.match('^\\w+').pop(); // match upto '/'
      assignInputNameToInputModel(inputName, ngModel);

      var formName = attrs.myName.match('\\w+$').pop(); // match after '/'
      findForm(formName, ngModel, scope);
    } // end link
  } // end return

  function checkInputFormat(attrs){
    if( !/\w\/\w/.test(attrs.rsName )){
      throw myNameError + "Formatting should be \"inputName/formName\" but is " + attrs.rsName
    }
  }

  function assignInputNameToInputModel(inputName, ngModel){
    ngModel.$name = inputName
  }

  function addInputNameToForm(formName, ngModel, scope){
    scope[formName][ngModel.$name] = ngModel; return
  }

  function findForm(formName, ngModel, scope){
    if( !scope ){ // ran out of scope before finding scope[formName]
      throw myNameError + "<Form> element named " + formName + " could not be found."
    }

    if( formName in scope){ // found scope[formName]
      addInputNameToForm(formName, ngModel, scope)
      return
    }
    findForm(formName, ngModel, scope.$parent) // recursively search through $parent scopes
  }
});

Это должно обрабатывать многие ситуации, когда вы просто не знаете, где будет форма. Или, возможно, у вас есть вложенные формы, но по какой-то причине вы хотите прикрепить это входное имя к двум формам? Ну, просто передайте имя формы, к которой вы хотите присоединить имя ввода.

То, что я хотел, - это способ назначать динамические значения входным данным, которые я никогда не узнаю, а затем просто вызывать $ scope.myFormName. $ Valid.

Это может быть излишним, и лучшее решение существует в 1.3+. Я не мог найти его за то время, что у меня было. Это работает для меня сейчас.

Удачи! Надеюсь, это поможет кому-то !!!!

2
SoEzPz

Похоже, что в Angular 1.3 это исправлено ( https://stackoverflow.com/a/32907176/3854385 )

Теперь это возможно с Angular 1.3+:

<form name="vm.myForm" novalidate>
  <div ng-repeat="p in vm.persons">
    <input type="text" name="person_{{$index}}" ng-model="p" required>
    <span ng-show="vm.myForm['person_' + $index].$invalid">Enter a name</span>
  </div>
</form>

Демо

В некоторых случаях внутренняя форма является хорошим решением, если вы можете просто передать информацию: ( https://stackoverflow.com/posts/12044600/ ) Чтобы решить проблему с «динамическим именем» you необходимо создать внутреннюю форму (см. ng-form ):

<div ng-repeat="social in formData.socials">
      <ng-form name="urlForm">
            <input type="url" name="socialUrl" ng-model="social.url">
            <span class="alert error" ng-show="urlForm.socialUrl.$error.url">URL error</span>
            <button ng-click="doSomething(urlForm.socialUrl.$valid)">Test</button>
      </ng-form>
  </div>

Другой альтернативой будет написать специальную директиву для этого.

Вот jsFiddle, показывающий использование ngForm: http://jsfiddle.net/pkozlowski_opensource/XK2ZT/2/

20
Loren

работа у меня с Angular 1.2.7

директива:

var DynamicName = function() {
    return {
        restrict: 'A',
        priority: -1,
        require: ['ngModel'],
        link: function (scope, element, attr, ngModel) {
            ngModel[0].$name = attr.name;
        }
    };
};

app.directive('dynamicName', DynamicName);

как пользоваться:

<div ng-repeat="phone in hrModel.phones">
    <input type="text"
           name="phones[{{$index}}]"
           ng-model="phones[$index]"
           dynamic-name
    />
</div>
0
ahiipsa