21

Come si userebbe formName.inputName. $ Valido quando "inputName" è stato creato dinamicamente?Attributo nome modulo dinamico <input type = "text" name = "{{nome-variabile}}" /> in Angularjs

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

L'uscita dell'ingresso attributo 'nome' HTML sarebbe la stringa "variablename", che applicato a tutti gli ingressi ripetuti.

Se abbiamo provato questo

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

L'uscita dell'ingresso attributo 'nome' HTML sarebbe la stringa "{{variable.name}}", che sarebbe applicato a tutti gli ingressi ripetuti.

In entrambe queste due condizioni, un attributo nome per ciascuno degli elementi di input ripetuti non sarebbe stato creato dinamicamente; TUTTI gli input condividono lo stesso nome di input. Non molto utile se si desidera chiamare un input specifico in base a un nome specifico.

  • necessità di utilizzare il nome dinamico Valori
  • devono essere in grado di chiamare $ scope.formName.dynamicName. $ Valida
  • devono essere in grado di chiamare $ scope.formName. $ Valida
  • necessità campi di input del nome dinamico da aggiungere al modulo nidificato o al modulo master
+0

http://stackoverflow.com/questions/21455695/angularjs-dynamic-form-field-validation/21457121#21457121 –

risposta

1

Non sono riuscito a trovare la risposta che soddisfacesse alcune o tutte queste esigenze. Questo è quello che mi è venuto in mente.

Potrebbe esserci un modo migliore, quindi per favore condividi i tuoi pensieri.
Sto usando Angularjs 1.3.0-beta.8

Ho una forma con le direttive multi-nidificati che tutte contengono ingresso (s), selezionare (s), ecc ... Questi elementi sono tutti racchiusi in ng-ripetizioni e valori di stringa dinamici.

Questo è come utilizzare la direttiva:

<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> 

Nota: è possibile aggiungere e indice per la concatenazione di stringhe, se avete bisogno di serializzare forse un tavolo di ingressi; che è quello che ho fatto. Tuttavia, gli input di nomi dinamici significano che potresti non conoscere il nome dell'input del modulo, quindi come chiameresti $ scope.formName. ??????. È possibile eseguire l'iterazione dell'oggetto $ scope.formName per ottenere chiavi che corrispondono a un determinato valore. Ciò significa concatenazione di stringhe in questo modo:

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

Poi nel $ scope.myFormName si dovrebbe trovare un nome qualsiasi modulo di input, semplicemente scorrendo sopra l'oggetto e la raccolta di tutte le chiavi che hanno incluso 'ciao'.

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

Questo dovrebbe gestire molte situazioni in cui semplicemente non si sa dove sarà il modulo. O forse hai moduli annidati, ma per qualche motivo vuoi collegare questo nome di input a due moduli? Bene, basta passare il nome del modulo a cui si desidera allegare il nome di input.

Quello che volevo, era un modo per assegnare valori dinamici agli input che non saprò mai, e poi chiamare $ scope.myFormName. $ Valido.

Questo può essere eccessivo e una soluzione migliore esiste in 1.3+. Non riuscivo a trovarlo nel tempo che avevo. Questo funziona per me ora.

Buona fortuna! Spero che questo aiuti qualcuno !!!!

+0

sicuramente aiutato con la mia situazione nidificato.Ho fatto una piccola correzione: nella funzione 'checkInputFormat' dovresti controllare' attrs.myName'. –

+0

Oh btw, qual è la soluzione migliore che esiste in AngularJS 1.3+? –

+0

Non l'ho ancora trovato. Continuerò a cercare. – SoEzPz

-1

Non dimenticare che è possibile accedere agli oggetti javascript utilizzando la notazione degli array con indici stringa. Dato il seguente oggetto arbitraria definizione del modulo:

$scope.form_def = { 
    form_name : 'BallForm', 
    variables : [ 
    height : { name : 'Height', type : 'text' }, 
    width : { name : 'Width', type : 'text' }, 
    color : { name : 'Color', type : 'multi', options : ['red', 'green', 'blue'] } 
    ] 
}; 
$scope.form_values = {}; 

... e il frammento di codice HTML ...

<form name="{{ form_def.form_name }}"> 
    <div ng-repeat="variable in form_def.variables"> 
    <input ng-if="variable.type==='text'" type="text" name="{{ variable.name }}" ng-model="form_values[variable.name]"> 
    <select ng-if="variable.type==='multi'" name="{{ variable.name }}" ng-model="form_values[variable.name]"> 
     <option ng-repeat="opt in variable.options" value="{{ opt }}">{{ opt }}</option> 
    </select> 
    </div> 
</form> 

All'interno del controller che si avrebbe poi un bel form_values ​​oggetto per ogni campo che è possibile accedere ripetendo le chiavi nell'hash di form_def.variables.

C'è molto di più quando si inizia a scrivere questo tipo di script generici di elaborazione dei moduli e si finisce con un sacco di codice spaghetti a mio parere e si sarebbe probabilmente meglio andare con meno soluzione generale, ma questa è un'altra domanda SO.

16

Sembra angolare fisso 1.3 questo (https://stackoverflow.com/a/32907176/3854385)

Questo è ora possibile con 1.3+ angolare:

<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> 

Demo

In alcuni casi una forma interna è una buona soluzione se puoi semplicemente passare le informazioni: (https://stackoverflow.com/posts/12044600/) Per risolvere il problema del 'nome dinamico' tu nee d per creare una forma interna (vedi 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> 

L'altra alternativa sarebbe quella di scrivere una direttiva personalizzato per questo.

Ecco l'jsFiddle mostrando l'uso del ngForm: http://jsfiddle.net/pkozlowski_opensource/XK2ZT/2/

+1

ng-show = "vm.myForm ['person _ {{$ index}}'] . $ invalid "dovrebbe essere ng-show =" vm.myForm ['person_' + $ index]. $ invalid "si aspetta un'espressione che valuta una stringa non una stringa –

+0

Ciò significherebbe che i due sarebbero equivalenti quindi, corretto ? O hai ricevuto qualche errore con la prima opzione? (Ho usato questo 1.x Angular in modo che dovrebbe funzionare lì. Se siete su 2.x, potrebbero aver cambiato il modo in cui valuta le cose.) – Loren

+0

1.x angolare questo è un plunkr da documenti angolari modificati per l'uso il metodo che ho suggerito https://plnkr.co/edit/meW6azMBI60ZiRA1GQcU?p=preview questo è un plunkr che usa il metodo di interpolazione https://plnkr.co/edit/ibzhEhCNPLqZCflXHLW3?p=preview come puoi vedere porta a ngMessages valore non analizzato correttamente –

0

lavoro per me con angolare 1.2.7

direttiva:

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

howtouse:

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

Compilando il tuo Nome ingresso

  1. Come qualcun altro ha sottolineato, versioni moderne di angolare hanno fissato questo ...
  2. Questo dovrebbe impostare l'attributo nome sul vostro contributo, e aggiungere il controller modello per la forma:
 
    angular.module('MOD') 
     .directive('compiledName', compiledNameDirective); 

    function compiledNameDirective() { 
     return { 
      restrict: 'A', 
      require: ['ngModel', '?^form'], 
      scope: { 
       name: '@compiledName' 
      }, 
      link: function checkboxIndeterminateLink(scope, element, attributes, required) { 
       var ngModelController = required[0], ngFormController = required[1]; 
       ngModelController.$name = scope.name; 
       element.attr('name', scope.name); 
       if (ngFormController) ngFormController.$addControl(ngModelController); 
      } 
     }; 
    } 


    

Problemi correlati