2016-05-02 21 views
15

Sto spostando il mio codice base legacy sull'architettura del nuovo componente promosso con AngularJS 1.5. Ho riscontrato un problema nel fare ciò per moduli più grandi. Tradizionalmente, vorrei collegare validazione dei form come segue:Passaggio del modulo al componente AngularJS per la convalida

<form name="myForm"> 
    <input type="text" name="input1" ng-model="vm.input1" required /> 
    <div ng-messages="myForm.input1.$error"> 
    <div ng-message="required">Please fill out this field.</div> 
    </div> 
    <!-- many more inputs --> 
</form> 

Durante la transizione a un'architettura a componenti, devo passare in modo esplicito il modulo per il componente:

<form name="vm.myForm"> 
    <my-awesome-input-component model="vm.input1" form="vm.myForm"><my-awesome-input-component> 
    <!-- many more inputs --> 
</form> 

Vorrei evitare di inquinare l'vm con la mia forma. Esiste un modo migliore per ottenere l'architettura dei componenti desiderata per i moduli?

+0

Non dovrebbe essere necessario inquinare il vostro modello di vista, il nome del modulo è puramente il nome per il controller forme, che si potrebbe passare al vostro ingresso componente. Il tuo modello di visualizzazione dovrebbe solo preoccuparsi dei valori di input. –

risposta

19

Update - ha cambiato forma nome--forma riferimento, dal momento che non è stato esplicito che noi stavamo passando il riferimento forma e non solo il nome del modulo. Questo può essere chiamato qualunque cosa tu voglia, solo essere chiaro di quello che realmente è.

Come dice il commento di Iain Reid, non è necessario utilizzare VM per questo. È solo un nome al modulo di tutto quello che vuoi e poi passare quel nome al componente, quindi sarebbe simile a questa:

<form name="myForm" ng-submit="ctrl.someFunction()" novalidate> 
    <my-input form-reference="myForm"></my-input> 
    <button type="submit">Some button</button> 
</form> 

Fare in modo che si scrive "novalidate" nel modulo per disabilitare le convalide del browser di default, se si voglio gestire le convalide da solo (che con l'uso di ng-messaggi penso che tu faccia).

Poi da lì, sul mio componente avrei scritto qualcosa del tipo:

angular.module("myApp") 
    .component("myInput",{ 
    templateUrl:'path/to/template.html' 
    bindings:{ 
     formReference:'<', 
     myInputModel:'<', 
     onUpdate:'&' 
    }, 
    controller: MyInputController 
    } 

E poi nel modello di ingresso:

<input type="text" name="myInput" ng-model="$ctrl.myInputModel" ng-change="$ctrl.update($ctrl.myInputModel)" required /> 
<div ng-messages="$ctrl.formReference.myInput.$error"> 
    <div ng-message="required">Please fill out this field.</div> 
</div> 

Alcune note aggiuntive sulle legature e come passare e aggiornare i modelli:

  • '< ': significa vincolo unidirezionale, che Angular dice di utilizzare per tutti i componenti da ora in poi. Per aggiornare il valore e avere un binding a due vie , è necessario includere una funzione "onUpdate".
  • onUpdate: '&' quello che sto dicendo qui è che io passerò una funzione per aggiornare il modello (un callback per gli eventi dei componenti).

Così nel controller di input avrei scritto qualcosa del tipo:

function MyInputController(){ 
    var ctrl = this; 
    ctrl.update = function(value){ 
     ctrl.onUpdate({value: value}); 
    }; 
} 

E, infine, quando muovo il componente all'interno di un modulo:

<form name="myForm" ng-submit="ctrl.someFunction()" novalidate> 
    <my-input form-reference="myForm" my-input-model="ctrl.anyModelIWant" on-update="ctrl.updateMyInput(value)"></my-input> 
    <button type="submit">Some button</button> 
</form> 

E il controllore della forma avrebbe avere una funzione:

... 
ctrl.updateMyInput = function(value){ 
    ctrl.anyModelIWant = value; 
} 
... 

Documenti ufficiali: https://docs.angularjs.org/guide/component

Spero che tutto questo aiuta qualcuno là fuori :-)

+1

Un grande esempio, ma una cosa che potrebbe confondere: nell'esempio che hai fornito, non stai legando il nome del modulo ("myForm") al componente: stai vincolando il riferimento effettivo al modulo. Comunque, funziona alla grande, ma all'inizio mi ha confuso un po '. –

+0

@SpencerSchneidenbach Buona cattura. È corretto – RGonzalez

Problemi correlati