AngularJS non invia valore di campo nascosto


192

Per un caso d'uso specifico devo presentare un unico modulo alla "vecchia maniera". Significa che uso un modulo con action = "". La risposta è trasmessa in streaming, quindi non sto ricaricando la pagina. Sono pienamente consapevole del fatto che una tipica app AngularJS non invierebbe un modulo in questo modo, ma finora non ho altra scelta.

Detto questo, ho cercato di popolare alcuni campi nascosti da Angular:

<input type="hidden" name="someData" ng-model="data" /> {{data}}

Si noti che viene mostrato il valore corretto nei dati.

Il modulo si presenta come un modulo standard:

<form id="aaa" name="aaa" action="/reports/aaa.html" method="post">
...
<input type="submit" value="Export" />
</form>

Se premo invio, nessun valore viene inviato al server. Se cambio il campo di input per digitare "testo", funziona come previsto. La mia ipotesi è che il campo nascosto non sia realmente popolato, mentre il campo di testo viene effettivamente visualizzato a causa della rilegatura bidirezionale.

Qualche idea su come posso inviare un campo nascosto popolato da AngularJS?


4
Hmm ... che ne dici di scrivere il testo display: none;,? È brutto però. Angolare ignora gli elementi nascosti.
tymeJV,

mettilo come risposta @tymeJV!
Jeroen Ingelbrecht,

7
Io uso la seguente sintassi per associare un valore di: <input type="hidden" required ng-model="data.userid" ng-init="data.userid=pivot.id" /> . Questo potrebbe non essere il modo corretto di fare ma funziona per me.
John P,

Risposte:


287

Non è possibile utilizzare la doppia rilegatura con campo nascosto. La soluzione è utilizzare le parentesi:

<input type="hidden" name="someData" value="{{data}}" /> {{data}}

EDIT: vedi questa discussione su github: https://github.com/angular/angular.js/pull/2574

MODIFICARE:

Da Angular 1.2, è possibile utilizzare la direttiva 'ng-value' per associare un'espressione all'attributo value dell'input. Questa direttiva dovrebbe essere utilizzata con la radio di input o la casella di controllo ma funziona bene con input nascosto.

Ecco la soluzione usando ng-value:

<input type="hidden" name="someData" ng-value="data" />

Ecco un violino che utilizza ng-value con un input nascosto: http://jsfiddle.net/6SD9N


Eccezionale. Molte grazie. Stavo quasi per nascondere il campo di testo, ma ora sento che questa è un'ottima soluzione.
Christian,

22
Grande. E puoi anche usare ng-value = "modelName" per farlo senza parentesi.
Jonathan,

2
Esatto, poiché Angular 1.2, è possibile utilizzare ng-value per associare un'espressione all'attributo value, la risposta è aggiornata.
Mickael,

hai davvero bisogno di un campo nascosto più quando usi AngularJS? su ngSubmit hai colpito un controller tutti i tuoi dati sono completamente visibili per l'accesso e li invii tramite un servizio $ http.
mtpultz,

3
Molte grazie. Il fatto che ng-model non possa essere utilizzato per input nascosti dovrebbe essere documentato in AngularJS IMO.
Yoonchee,

47

Puoi sempre usare un type=texte display:none;poiché Angolare ignora gli elementi nascosti. Come dice OP, normalmente non lo faresti, ma questo sembra un caso speciale.

<input type="text" name="someData" ng-model="data" style="display: none;"/>

Grazie! Ho pensato nella stessa direzione, ma ho dovuto semplicemente preferire la soluzione {{}} di Mickael.
Christian,

1
soluzione intelligente / intelligente
ImranNaqvi

8

Nel controller:

$scope.entityId = $routeParams.entityId;

Nella vista:

<input type="hidden" name="entityId" ng-model="entity.entityId" ng-init="entity.entityId = entityId" />

1
Buon punto ... Preferirei farlo solo nel controller la prossima volta
meffect

mi sto innamorando di ng-init
ImranNaqvi

No in loop crea molti problemi e assegna l'ultimo valore a tutti entityIdse entityIdè un array
ImranNaqvi

4

Ho trovato una bella soluzione scritta da Mike su sapiensworks . È semplice come usare una direttiva che controlla le modifiche al tuo modello:

.directive('ngUpdateHidden',function() {
    return function(scope, el, attr) {
        var model = attr['ngModel'];
        scope.$watch(model, function(nv) {
            el.val(nv);
        });
    };
})

e quindi associare l'input:

<input type="hidden" name="item.Name" ng-model="item.Name" ng-update-hidden />

Ma la soluzione fornita da tymeJV potrebbe essere migliore in quanto l'input nascosto non genera l'evento change in javascript come yycorman ha detto in questo post, quindi quando si modifica il valore tramite un plug-in jQuery continuerà a funzionare.

Modifica Ho modificato la direttiva per applicare un nuovo valore al modello quando viene attivato l'evento change, quindi funzionerà come testo di input.

.directive('ngUpdateHidden', function () {
    return {
        restrict: 'AE', //attribute or element
        scope: {},
        replace: true,
        require: 'ngModel',
        link: function ($scope, elem, attr, ngModel) {
            $scope.$watch(ngModel, function (nv) {
                elem.val(nv);
            });
            elem.change(function () { //bind the change event to hidden input
                $scope.$apply(function () {
                    ngModel.$setViewValue(  elem.val());
                });
            });
        }
    };
})

quindi quando si attiva un $("#yourInputHidden").trigger('change')evento con jQuery, verrà aggiornato anche il modello associato.


Qualcun altro ha problemi a far funzionare questa soluzione? Il problema è che il parametro ngModel non è definito quando la direttiva viene analizzata ed eseguita, quindi $ watch non viene aggiunto.
Icfantv,

Ok. Sembra che il problema sia che il quarto parametro ngModel sia un oggetto, mentre l'esempio a cui fa riferimento il collegamento in sapiensworks recupera il valore di stringa dell'attributo ng-model tramite attr ['ngModel'] e quindi lo passa all'orologio. Posso confermare che apportare questa modifica risolve il problema dell'orologio.
Icfantv,

C'è un altro problema qui. jQuery non genera un evento di modifica quando si modifica a livello di codice il valore di un campo di input nascosto. Quindi, se dico $ (hidden_input_elt) .val ("snoopy") devo anche aggiungere .change () per far sì che l'evento change venga generato. Il problema è che Angular si lamenterà di $ scope.apply () perché è già in $ apply è già in corso. La soluzione qui è rimuovere $ scope. $ Apply nella funzione change sopra e chiamare semplicemente ngModel. $ SetViewValue (...).
Icfantv,

2

Abbiamo trovato uno strano comportamento su questo valore nascosto () e non possiamo farlo funzionare.

Dopo aver giocato, abbiamo scoperto che il modo migliore è semplicemente definire il valore nel controller stesso dopo l'ambito del modulo.

.controller('AddController', [$scope, $http, $state, $stateParams, function($scope, $http, $state, $stateParams) {

    $scope.routineForm = {};
    $scope.routineForm.hiddenfield1 = "whatever_value_you_pass_on";

    $scope.sendData = function {

// JSON http post action to API 
}

}])

1

L'ho raggiunto tramite -

 <p style="display:none">{{user.role="store_user"}}</p>

1

aggiorna la risposta di @tymeJV, ad esempio:

 <div style="display: none">
    <input type="text" name='price' ng-model="price" ng-init="price = <%= @product.price.to_s %>" >
 </div>

0

Ho avuto lo stesso problema, ho davvero bisogno di inviare una chiave dal mio jsp allo script java, ho impiegato circa 4 ore o più della mia giornata per risolverlo.

Includo questo tag sul mio JavaScript / JSP:

 $scope.sucessMessage = function (){  
    	var message =     ($scope.messages.sucess).format($scope.portfolio.name,$scope.portfolio.id);
    	$scope.inforMessage = message;
    	alert(message);  
}
 

String.prototype.format = function() {
    var formatted = this;
    for( var arg in arguments ) {
        formatted = formatted.replace("{" + arg + "}", arguments[arg]);
    }
    return formatted;
};
<!-- Messages definition -->
<input type="hidden"  name="sucess"   ng-init="messages.sucess='<fmt:message  key='portfolio.create.sucessMessage' />'" >

<!-- Message showed affter insert -->
<div class="alert alert-info" ng-show="(inforMessage.length > 0)">
    {{inforMessage}}
</div>

<!-- properties
  portfolio.create.sucessMessage=Portf\u00f3lio {0} criado com sucesso! ID={1}. -->

Il risultato è stato: Portfólio 1 criado com sucesso! ID = 3.

I migliori saluti


0

Nel caso in cui qualcuno abbia ancora problemi con questo, ho avuto un problema simile quando ho cercato di tenere traccia della sessione utente / userid su modulo multipagina

L'ho risolto aggiungendo

.when ("/ q2 /: uid" nel routing:

    .when("/q2/:uid", {
        templateUrl: "partials/q2.html",
        controller: 'formController',
        paramExample: uid
    })

E aggiunto questo come campo nascosto per passare parametri tra le pagine del modulo web

<< input type = "nascosto" richiesto ng-model = "formData.userid" ng-init = "formData.userid = uid" />

Sono nuovo di Angular, quindi non sono sicuro che sia la migliore soluzione possibile, ma ora sembra funzionare bene per me


0

Assegna direttamente il valore al modello data-ng-valuenell'attributo. Poiché l'interprete angolare non riconosce i campi nascosti come parte di ngModel.

<input type="hidden" name="pfuserid" data-ng-value="newPortfolio.UserId = data.Id"/>

0

Uso un javascript classico per impostare il valore su input nascosto

$scope.SetPersonValue = function (PersonValue)
{
    document.getElementById('TypeOfPerson').value = PersonValue;
    if (PersonValue != 'person')
    {
        document.getElementById('Discount').checked = false;
        $scope.isCollapsed = true;
    }
    else
    {
        $scope.isCollapsed = false;
    }
}

0

Sotto il codice funzionerà per questo IFF, nello stesso ordine in cui è menzionato, assicurati che il tuo ordine sia digitare quindi nome, ng-modello ng-init, valore. questo è tutto.


0

Qui vorrei condividere il mio codice di lavoro:

<input type="text" name="someData" ng-model="data" ng-init="data=2" style="display: none;"/>
OR
<input type="hidden" name="someData" ng-model="data" ng-init="data=2"/>
OR
<input type="hidden" name="someData" ng-init="data=2"/>


potresti ulteriori spiegazioni per favore
JSmith

Sicuro! Quando utilizziamo un campo nascosto o un campo di testo con display: attributo none, l'utente non è in grado di inserire valore. In tal caso, la direttiva ng-init aiuta a impostare il valore per il campo. Grazie
J. Middya,

nel post intendevo Mi dispiace
JSmith
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.