2016-03-10 10 views
8

JSFiddle qui: http://jsfiddle.net/c6tzj6Lf/4/Disabilitare pulsante di invio in base a campi aggiunti con ng-bind-html

Sto generando dinamicamente forme e pulsanti e si desidera disattivare i pulsanti se gli ingressi di forma richiesti non sono stati completati.

HTML:

<div ng-app="choicesApp"> 
    <ng-form name="choicesForm" ng-controller="ChoicesCtrl"> 
    <div ng-bind-html="trustCustom()"></div> 
    <button ng-repeat="button in buttons" ng-disabled="choicesForm.$invalid"> 
     {{button.text}} 
    </button> 
    </ng-form> 
</div> 

JavaScript:

angular.module('choicesApp', ['ngSanitize']) 
    .controller('ChoicesCtrl', ['$scope', '$sce', function($scope, $sce) { 
    $scope.custom = "Required Input: <input required type='text'>"; 
    $scope.trustCustom = function() { 
     return $sce.trustAsHtml($scope.custom); 
    }; 
    $scope.buttons = [ 
     {text:'Submit 1'}, 
     {text:'Submit 2'}]; 
}]); 

choicesForm.$invalid è false e non cambia quando l'immissione del testo nel campo di immissione.

Soluzione:

ho finito per usare l'angolare-bind-html-compilare direttiva da qui: https://github.com/incuna/angular-bind-html-compile

Ecco il bit rilevante del codice di lavoro:

<ng-form name="choicesForm"> 
    <div ng-if="choices" bind-html-compile="choices"></div> 
    <button ng-click="submitForm()" ng-disabled="choicesForm.$invalid"> 
    Submit 
    </button> 
</ng-form> 

E le scelte potrebbero essere uno snippit di HTML come questo:

<div><strong>What is your sex?</strong></div> 
<div> 
    <input type="radio" name="gender" ng-model="gender" value="female" required> 
    <label for="female"> Female</label><br> 
    <input type="radio" name="gender" ng-model="gender" value="male" required> 
    <label for="male"> Male</label> 
</div> 
+0

si inietta la dipendenza ngSanitize? –

+0

Sì, ho appena aggiornato il violino, se hai guardato una versione precedente potrebbe essersi rotto. – disperse

+0

Quindi, qual è il problema? Riesco a vedere nel violino che i pulsanti sono abilitati/disabilitati. non lo è? –

risposta

6

Il problema principale è che ngBindHtml non compila il codice html - inserisce il codice HTML così com'è. Puoi anche controllare l'input dinamico e vedere che non ha lo (ng-pristine, ng-untouched, ecc.), Che è una bandiera rossa importante.

Nel tuo caso, il modulo semplicemente non sa che hai aggiunto un altro input o qualcosa è cambiato per quella materia. Il suo stato ($ pristine, $ valido, ecc.) Non è determinato dal suo codice HTML ma dal NgModelControllers registrato. Questi controller vengono aggiunti automaticamente quando un ngModel è collegato.

  • Per esempio, questo <input required type='text'> non influenzerà la validità del modulo, anche se è necessario, dal momento che non ha ngModel ad essa assegnati.
  • Ma questo <div ng-model="myDiv" required></div> influisce su di esso poiché è richiesto e ne è stato assegnato ngModel.

La direttiva ngDisabled sui tasti funziona come previsto dal momento che dipende dalla form's $invalid property.

Vedere questo fiddle che mostra come ngModel registra il proprio controller. Si noti che l'html contenente l'input dinamico viene compilato dopo 750 ms solo per mostrare come è possibile aggiungere NgModelControllers dopo l'istanza di FormController.

ci sono un paio di soluzioni nel tuo caso:

  • utilizzare una direttiva personalizzato per legare e compilare html - come this one

  • uso ngInclude che fa compilare l'html

  • uso $compile per compilare l'HTML appena aggiunto, ma questo è un po 'complicato in quanto non si sa esattamente quando eseguire questa azione

2

Questa è una risposta ancora incompleta perché al momento non riesco a eseguire il codice.

Penso che il tuo html sarà incluso, non compilato. Quindi gli input non sono legati all'angolazione e non fanno parte dell'oggetto della forma angolare.

L'unico modo che vedo è utilizzare una direttiva che compilerà il codice HTML passato e lo aggiungerà al modulo. Questo può essere abbastanza complicato, però, se vuoi procedere in questo modo ti suggerisco di modificare la tua domanda per chiedere la suddetta direttiva.

Tuttavia io non sono davvero familiarità con $ compilo in modo che io non so se funzionerà per aggiungere solo $ compilare circa $ sce.trustAsHtml()

1

È possibile scrivere un metodo come ng-disabled non funziona con booleani, funziona con la stringa 'controllato' invece:

Così il vostro posto di controllo un metodo:

$scope.buttonDisabled = function(invalid){ 
     return invalid ? "checked" : ""; 
    }; 

E sulla vostra vista lo usano sull'espressione angolare:

<button ng-repeat="button in buttons" ng-disabled="buttonDisabled(choicesForm.$invalid)"> 

Ecco un lavoro fiddle

+0

Non sono sicuro che sia questo il problema.Notare che mettere il testo nella casella di testo "Inserimento statico" abiliterà i pulsanti, ma non inserire il testo nella casella di testo "Inserimento statico". – disperse

1

Working DEMO

Questa è la soluzione che state cercando. Hai bisogno di una direttiva personalizzata. Nel mio esempio ho usato una direttiva denominata compile-template e l'ho incorporata nell'elemento div.

<div ng-bind-html="trustCustom()" compile-template></div> 

Codice direttiva:

.directive('compileTemplate', function($compile, $parse){ 
    return { 
     link: function(scope, element, attr){ 
      var parsed = $parse(attr.ngBindHtml); 
      function getStringValue() { return (parsed(scope) || '').toString(); } 

      //Recompile if the template changes 
      scope.$watch(getStringValue, function() { 
       $compile(element, null, -9999)(scope); //The -9999 makes it skip directives so that we do not recompile ourselves 
      }); 
     }   
    } 
}); 

ho trovato la direttiva in this fiddle.

+0

Hmm, non sembra funzionare. Prova ad inserire del testo nella casella di testo Dynamic Input, i pulsanti non sono abilitati. – disperse

+0

Come hai usato 'ng-disabled =" choicesForm. $ Invalid "condizione", il pulsante sarà abilitato solo se la forma totale è valida. Sono richiesti sia campi di input dinamici che statici. Se inserisci un valore solo in un campo di input, è richiesto un altro campo, il che significa che la forma non è valida. Se vuoi abilitare il pulsante dopo aver inserito l'input in uno dei due campi, il tuo codice dovrebbe essere qualcosa come questo 'ng-disabled =" choicesForm.staticField. $ Invalid o choicesForm.dynamicField. $ Invalid "' –

+0

Cosa vuoi veramente? ? vuoi abilitare il pulsante quando la forma totale è valida? o quando uno dei due campi di input è valido? –

1

Credo che cosa stia realmente succedendo, ma a causa di jsfiddle non sono in grado di analizzare gli scopi reali creati qui.

<div ng-app="choicesApp"> 
    <ng-form name="choicesForm" ng-controller="ChoicesCtrl"> 
    <div ng-bind-html="trustCustom()"></div> 
    <button ng-repeat="button in buttons" ng-disabled="choicesForm.$invalid"> 
     {{button.text}} 
    </button> 
    </ng-form> 
</div> 

Il primo div è il tuo ambito di livello superiore, il tuo modulo è il primo ambito figlio. Aggiungendo il div usando una funzione si crea il campo di input aggiunto dinamicamente come un figlio del primo figlio, un nipotino dello scope di primo livello. Pertanto il tuo modulo non è a conoscenza degli elementi che stai aggiungendo dinamicamente, causando solo il campo statico richiesto per l'immissione di moduli validi.

Una soluzione migliore sarebbe quella di utilizzare ng-inclue per campi modulo aggiuntivi o se il modulo non è troppo grande, quindi semplicemente metterli sulla pagina o sul modello che si sta utilizzando.

Problemi correlati