web-dev-qa-db-ja.com

Angularjsの動的フォーム名属性<input type = "text" name = "{{variable-name}}" />

「inputName」が動的に作成されたときに、誰かがformName.inputName。$ validをどのように使用しますか?

  <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}}"になり、すべての繰り返し入力に適用されます。

これらの2つの条件のいずれでも、繰り返される入力要素のそれぞれの名前属性は動的に作成されません。すべての入力は同じ入力名を共有します。特定の名前に基づいて特定の入力を呼び出したい場合、あまり良くありません。

  • 動的な名前の値を使用する必要があります
  • $ scope.formName.dynamicName。$ validを呼び出すことができる必要がある
  • $ scope.formName。$ validを呼び出すことができる必要がある
  • ネストされたフォームまたはマスターフォームに追加する動的な名前入力フィールドが必要
23
SoEzPz

これらのニーズの一部またはすべてを満たす答えが見つかりませんでした。これが私が思いついたものです。

もっと良い方法があるかもしれないので、あなたの考えを共有してください。
Angularjs 1.3.0-beta.8を使用しています

入力、選択などをすべて含む複数のネストされたディレクティブを持つフォームがあります。これらの要素はすべてng-repeatsおよび動的な文字列値で囲まれています。

これは、ディレクティブの使用方法です。

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

これは、フォームがどこにあるかわからない多くの状況を処理する必要があります。または、ネストされたフォームがあるかもしれませんが、何らかの理由で、この入力名を2つのフォームに添付する必要がありますか?さて、入力名を添付したいフォーム名を渡すだけです。

私が欲しかったのは、動的な値を私が決して知らない入力に割り当て、その後$ 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/ )「動的な名前」の問題を解決するには内部フォームを作成する必要があります( 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>

他の選択肢は、このためのカスタムディレクティブを記述することです。

NgFormの使用法を示すjsFiddleを次に示します。 http://jsfiddle.net/pkozlowski_opensource/XK2ZT/2/

21
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