web-dev-qa-db-fra.com

AngularJS n'envoie pas de valeur de champ caché

Pour un cas d'utilisation spécifique, je dois soumettre un formulaire unique à l'ancienne. Cela signifie que j'utilise un formulaire avec action = "". La réponse est diffusée en continu, je ne recharge donc pas la page. Je suis tout à fait conscient qu'une application typique d'AngularJS ne soumettrait pas un formulaire de cette façon, mais je n'ai pas d'autre choix.

Cela dit, j'ai essayé de renseigner des champs cachés dans Angular:

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

Veuillez noter que la valeur correcte dans les données est affichée.

Le formulaire ressemble à un formulaire standard:

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

Si je frappe sur Envoyer, aucune valeur n'est envoyée au serveur. Si je modifie le champ de saisie pour taper "text", cela fonctionne comme prévu. Mon hypothèse est que le champ caché n'est pas vraiment rempli, alors que le champ de texte est affiché en raison d'une liaison bidirectionnelle.

Des idées comment je peux soumettre un champ caché rempli par AngularJS?

190
Christian

Vous ne pouvez pas utiliser la double liaison avec un champ caché. La solution consiste à utiliser des crochets:

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

EDIT: Voir ce fil sur github: https://github.com/angular/angular.js/pull/2574

MODIFIER:

Depuis Angular 1.2, vous pouvez utiliser la directive 'ng-value' pour lier une expression à l'attribut value de l'entrée. Cette directive devrait être utilisée avec une radio d'entrée ou une case à cocher mais fonctionne bien avec une entrée cachée.

Voici la solution en utilisant ng-value:

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

Voici un violon utilisant ng-value avec une entrée cachée: http://jsfiddle.net/6SD9N

286
Mickael

Vous pouvez toujours utiliser un type=text et display:none; puisque Angular ignore les éléments masqués. Comme le dit OP, normalement, vous ne feriez pas cela, mais cela semble être un cas spécial.

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

Dans le contrôleur:

$scope.entityId = $routeParams.entityId;

Dans la vue:

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

J'ai trouvé une solution intéressante écrite par Mike sur sapiensworks . C'est aussi simple que d'utiliser une directive qui surveille les changements sur votre modèle:

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

et liez ensuite votre entrée:

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

Mais la solution fournie par tymeJV pourrait être meilleure, car une entrée cachée ne déclenche pas d'événement de changement en javascript, comme le dit yycorman le this post, donc, le fait de modifier la valeur via un plugin jQuery fonctionnera toujours.

Éditer J'ai modifié la directive pour appliquer la nouvelle valeur au modèle lorsque l'événement change est déclenché. Il fonctionnera donc comme un texte d'entrée.

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

ainsi, lorsque vous déclencherez l'événement $("#yourInputHidden").trigger('change') avec jQuery, le modèle lié sera également mis à jour.

4
Joan JB

Trouvé un comportement étrange à propos de cette valeur cachée () et nous ne pouvons pas le faire fonctionner.

Après avoir joué, nous avons trouvé que le meilleur moyen est de définir la valeur dans le contrôleur lui-même après la portée du formulaire.

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

}])
2
dcpartners

mettre à jour la réponse de @tymeJV, par exemple:

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

J'ai réalisé ceci via -

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

Ici, j'aimerais partager mon code de travail:

<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"/>
0
J. Middya

J'utilise un javascript classique pour définir la valeur d'entrée masquée

$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
Ivan Kuznietsov

Juste au cas où quelqu'un aurait encore du mal avec ça, j'ai eu le même problème en essayant de garder une trace de la session utilisateur/utilisateur sur un formulaire multipage

J'ai corrigé cela en ajoutant

.when ("/ q2 /: uid" dans le routage:

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

Et ajouté ceci comme un champ caché pour passer des paramètres entre les pages webform

<< type d'entrée = "caché" requis ng-model = "formData.userid" ng-init = "formData.userid = uid" />

Je ne connais pas Angular, donc je ne suis pas sûr que ce soit la meilleure solution possible, mais cela semble fonctionner pour moi maintenant.

0
macieku

Affectez directement la valeur au modèle dans l'attribut data-ng-value. Puisque Angular, l'interpréteur ne reconnaît pas les champs cachés dans ngModel.

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

Le code ci-dessous fonctionnera pour cet IFF dans le même ordre que celui indiqué, assurez-vous que vous commandez est de type puis nom, ng-model ng-init, value. c'est ça.

0
Pawan Parashar

J'avais face au même problème, j'ai vraiment besoin d'envoyer une clé de mon jsp au script Java, cela prend environ 4h ou plus de ma journée pour le résoudre.

J'inclus cette balise sur mon 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}. -->

Le résultat a été: Portfólio 1 criado com sucesso! ID = 3.

Meilleures salutations

0
LeoJava