AngularJS no envía valor de campo oculto

192

Para un caso de uso específico, tengo que enviar un formulario único a la "antigua". Significa que uso un formulario con action = "". La respuesta se transmite, por lo que no estoy volviendo a cargar la página. Soy completamente consciente de que una aplicación típica de AngularJS no enviaría un formulario de esa manera, pero hasta ahora no tengo otra opción.

Dicho esto, traté de llenar algunos campos ocultos de Angular:

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

Tenga en cuenta que se muestra el valor correcto en los datos.

El formulario se parece a un formulario estándar:

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

Si presiono enviar, no se envía ningún valor al servidor. Si cambio el campo de entrada para escribir "texto", funciona como se esperaba. Mi suposición es que el campo oculto no está realmente poblado, mientras que el campo de texto en realidad se muestra debido al enlace bidireccional.

¿Alguna idea de cómo puedo enviar un campo oculto poblado por AngularJS?

cristiano
fuente
44
Hmm ... ¿qué tal escribir texto display: none;? Es feo aunque. Angular ignora los elementos ocultos.
tymeJV
poner eso como la respuesta @tymeJV!
Jeroen Ingelbrecht
77
Yo uso la siguiente sintaxis para enlazar un valor de: <input type="hidden" required ng-model="data.userid" ng-init="data.userid=pivot.id" /> . Puede que esta no sea la forma correcta de hacerlo, pero funciona para mí.
John P

Respuestas:

287

No puede usar doble enlace con campo oculto. La solución es usar corchetes:

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

EDITAR: Vea este hilo en github: https://github.com/angular/angular.js/pull/2574

EDITAR:

Desde Angular 1.2, puede usar la directiva 'ng-value' para vincular una expresión al atributo de valor de entrada. Esta directiva debe usarse con radio de entrada o casilla de verificación pero funciona bien con entrada oculta.

Aquí está la solución usando ng-value:

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

Aquí hay un violín que usa ng-value con una entrada oculta: http://jsfiddle.net/6SD9N

Mickael
fuente
Increíble. Muchas gracias. Casi iba a ocultar el campo de texto, pero ahora siento que esta es una gran solución.
Christian
22
Excelente. Y también puede usar ng-value = "modelName" para hacerlo sin corchetes.
Jonathan
2
Así es, desde Angular 1.2, puede usar ng-value para vincular una expresión al atributo de valor, la respuesta está actualizada.
Mickael
¿Realmente necesitas un campo oculto cuando usas AngularJS? en ngSubmit golpeas un controlador, todos tus datos son completamente visibles para el acceso, y los envías a través de algún servicio $ http.
mtpultz
3
Muchas gracias. El hecho de que ng-model no pueda usarse para entradas ocultas debe documentarse en AngularJS IMO.
yoonchee
47

Se puede utilizar siempre una type=texty display:none;ya no hace caso angular elementos ocultos. Como dice OP, normalmente no harías esto, pero esto parece un caso especial.

<input type="text" name="someData" ng-model="data" style="display: none;"/>
tymeJV
fuente
¡Gracias! Pensé en la misma dirección, pero simplemente tenía que preferir la solución {{}} de Mickael.
Christian
1
solución inteligente / inteligente
ImranNaqvi
8

En el controlador:

$scope.entityId = $routeParams.entityId;

En la vista:

<input type="hidden" name="entityId" ng-model="entity.entityId" ng-init="entity.entityId = entityId" />
efecto
fuente
1
Buen punto ... Preferiría hacer esto solo en el controlador la próxima vez
mefefectó el
Me estoy enamorando de ng-init
ImranNaqvi
Nooo en bucle, causa muchos problemas y asigna el último valor a todos entityIdsi entityIdes una matriz
ImranNaqvi
4

He encontrado una buena solución escrita por Mike en sapiensworks . Es tan simple como usar una directiva que vigila los cambios en su modelo:

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

y luego vincula tu entrada:

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

Pero la solución proporcionada por tymeJV podría ser mejor ya que la entrada oculta no activa el evento de cambio en javascript como yycorman dijo en esta publicación, por lo que al cambiar el valor a través de un complemento jQuery aún funcionará.

Editar He cambiado la directiva para aplicar un nuevo valor al modelo cuando se activa el evento de cambio, por lo que funcionará como un texto de entrada.

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

así que cuando desencadena un $("#yourInputHidden").trigger('change')evento con jQuery, también actualizará el modelo enlazado.

Joan JB
fuente
¿Alguien más tiene problemas para que esta solución funcione? El problema es que el parámetro ngModel no está definido cuando la directiva se analiza y ejecuta, por lo tanto, $ watch no se agrega.
icfantv
Okay. Parece que el problema es que el cuarto parámetro ngModel es un objeto, mientras que el ejemplo al que se hace referencia desde el enlace en sapiensworks recupera el valor de cadena del atributo ng-model a través de attr ['ngModel'] y luego lo pasa al reloj. Puedo confirmar que hacer este cambio soluciona el problema del reloj.
icfantv
Hay otro problema aquí. jQuery no dispara un evento de cambio cuando cambia programáticamente el valor de un campo de entrada oculto. Entonces, si digo $ (hidden_input_elt) .val ("snoopy") también tengo que agregar .change () para que se active el evento de cambio. El problema con esto es que Angular se quejará del $ scope.apply () anterior porque ya está en un $ apply ya está en progreso. La solución aquí es eliminar el $ scope. $ Apply en la función de cambio anterior y simplemente llamar a ngModel. $ SetViewValue (...).
icfantv
2

Encontró un comportamiento extraño sobre este valor oculto () y no podemos hacerlo funcionar.

Después de jugar, descubrimos que la mejor manera es definir el valor en el controlador después del alcance del formulario.

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

}])
dcpartners
fuente
1

Lo logré a través de -

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

Actualice la respuesta de @tymeJV, por ejemplo:

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

Tenía el mismo problema, realmente necesito enviar una clave desde mi script jsp a java. Pasé alrededor de 4 horas o más de mi día para resolverlo.

Incluyo esta etiqueta en mi 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}. -->

El resultado fue: Portfólio 1 criado com sucesso! ID = 3.

Atentamente

LeoJava
fuente
0

En caso de que alguien todavía tenga problemas con esto, tuve un problema similar al intentar realizar un seguimiento de la sesión de usuario / ID de usuario en un formulario de varias páginas

Lo arreglé agregando

.when ("/ q2 /: uid" en la ruta:

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

Y agregó esto como un campo oculto para pasar parámetros entre páginas de formularios web

<< input type = "hidden" required ng-model = "formData.userid" ng-init = "formData.userid = uid" />

Soy nuevo en Angular, así que no estoy seguro de que sea la mejor solución posible, pero parece que funciona bien para mí ahora

macieku
fuente
0

Asigne directamente el valor al modelo en el data-ng-valueatributo. Dado que el intérprete angular no reconoce los campos ocultos como parte de ngModel.

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

Yo uso un javascript clásico para establecer el valor de entrada oculta

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

El siguiente código funcionará para este IFF en el mismo orden en que se menciona, asegúrese de que su pedido sea tipo y luego nombre, ng-model ng-init, valor. Eso es.

Pawan Parashar
fuente
0

Aquí me gustaría compartir mi código de trabajo:

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

J. Middya
fuente
¿podría
darme
¡Por supuesto! Cuando usamos un campo oculto o un campo de texto con display: ninguno, el usuario no puede ingresar valor. En ese caso, la directiva ng-init ayuda a establecer el valor para el campo. Gracias
J. Middya
en la publicación quise decir Perdón
JSmith