AngularJS не отправляет скрытое значение поля


192

Для конкретного случая использования я должен представить одну форму «по-старому». Значит, я использую форму с action = "". Ответ передается в потоковом режиме, поэтому я не перезагружаю страницу. Я полностью осознаю, что типичное приложение AngularJS не будет отправлять форму таким образом, но пока у меня нет другого выбора.

Тем не менее, я попытался заполнить некоторые скрытые поля из Angular:

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

Обратите внимание, правильное значение в данных отображается.

Форма выглядит как стандартная форма:

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

Если я нажму "отправить", никакое значение не будет отправлено на сервер. Если я изменю поле ввода на тип «текст», оно будет работать как положено. Я предполагаю, что скрытое поле на самом деле не заполнено, в то время как текстовое поле фактически отображается из-за двусторонней привязки.

Любые идеи, как я могу представить скрытое поле, заполненное AngularJS?


4
Хм ... а как насчет текста display: none;? Это ужасно Angular игнорирует скрытые элементы.
tymeJV

Поместите это как ответ @tymeJV!
Йерун Ингельбрехт

7
Я использую следующий синтаксис для привязки значения: <input type="hidden" required ng-model="data.userid" ng-init="data.userid=pivot.id" /> . Это не может быть правильным способом, но это работает для меня.
Джон П

Ответы:


287

Вы не можете использовать двойную привязку со скрытым полем. Решение заключается в использовании скобок:

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

РЕДАКТИРОВАТЬ: см. Эту тему на GitHub: https://github.com/angular/angular.js/pull/2574

РЕДАКТИРОВАТЬ:

Начиная с версии Angular 1.2, вы можете использовать директиву ng-value, чтобы связать выражение с атрибутом value ввода. Эта директива должна использоваться с входным радио или флажком, но хорошо работает со скрытым вводом.

Вот решение, использующее значение ng:

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

Вот скрипка, использующая ng-значение со скрытым вводом: http://jsfiddle.net/6SD9N


Потрясающие. Большое спасибо. Я почти собирался скрыть текстовое поле, но теперь я чувствую, что это отличный обходной путь.
Кристиан

22
Отлично. А также вы можете использовать ng-value = "modelName", чтобы сделать это без скобок.
Джонатан

2
Это верно, начиная с версии Angular 1.2, вы можете использовать ng-значение, чтобы связать выражение с атрибутом значения, ответ актуален.
Микаэль

вам действительно нужно скрытое поле больше, когда вы используете AngularJS? На ngSubmit вы нажимаете на контроллер, все ваши данные полностью видны для доступа, и вы отправляете их через какую-то службу $ http.
mtpultz

3
Большое спасибо. Тот факт, что ng-модель не может использоваться для скрытого ввода, должен быть задокументирован в AngularJS IMO.
yoonchee

47

Вы всегда можете использовать a type=textи display:none;Angular игнорирует скрытые элементы. Как говорит OP, обычно вы бы этого не делали, но это похоже на особый случай.

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

Спасибо! Я думал в том же направлении, но мне просто нужно было выбрать решение {{}} от Микаэля.
Кристиан

1
умное / умное решение
ImranNaqvi

8

В контроллере:

$scope.entityId = $routeParams.entityId;

По мнению:

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

1
Хороший вопрос ... Я бы предпочел сделать это только в контроллере в следующий раз
эффект от

я влюбился в нг-init
ImranNaqvi

Нееет. в цикле это создает много проблем и присваивает последнее значение всем, entityIdесли entityIdэто массив
ImranNaqvi

4

Я нашел хорошее решение, написанное Майком на sapiensworks . Это так же просто, как использовать директиву, которая отслеживает изменения в вашей модели:

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

а затем свяжите ваш ввод:

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

Но решение, предоставленное tymeJV, могло бы быть лучше, так как скрытый ввод не вызывает событие change в javascript, как рассказал yycorman в этом посте, поэтому при изменении значения через плагин jQuery все равно будет работать.

Изменить Я изменил директиву, чтобы применить новое значение обратно к модели, когда инициируется событие изменения, поэтому оно будет работать как текст ввода.

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

поэтому, когда вы запускаете $("#yourInputHidden").trigger('change')событие с помощью jQuery, оно также обновляет связанную модель.


У кого-то еще есть проблемы с этим решением? Проблема в том, что параметр ngModel не определен, когда директива анализируется и выполняется, таким образом, $ watch не добавляется.
icfantv

Хорошо. Похоже, проблема в том, что четвертый параметр ngModel является объектом, в то время как пример, на который ссылается ссылка в sapiensworks, получает строковое значение атрибута ng-model через attr ['ngModel'], а затем передает его в watch. Я могу подтвердить, что внесение этого изменения устраняет проблему с часами.
icfantv

Здесь есть еще одна проблема. jQuery не запускает событие изменения, когда вы программно изменяете значение скрытого поля ввода. Поэтому, если я скажу $ (hidden_input_elt) .val ("snoopy"), я должен также добавить .change (), чтобы вызвать событие change. Проблема в том, что Angular будет жаловаться на вышеуказанный $ scope.apply (), потому что он уже находится в $ apply, уже выполняется. Решение здесь состоит в том, чтобы удалить $ scope. $ Apply в функции изменения выше и просто вызвать ngModel. $ SetViewValue (...).
icfantv

2

Обнаружил странное поведение в отношении этого скрытого значения (), и мы не можем заставить его работать.

После игры мы обнаружили, что лучший способ - это просто определить значение в самом контроллере после области видимости.

.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

Я достиг этого через -

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

1

обновить ответ @tymeJV, например:

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

0

Я столкнулся с той же проблемой, мне действительно нужно отправить ключ из моего jsp в java-скрипт. На его решение уходит около 4 часов или больше моего дня.

Я включил этот тег в мой 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}. -->

Результат был: Portfólio 1 criado com sucesso! ID = 3.

Наилучшие пожелания


0

На всякий случай, если кто-то все еще борется с этим, у меня возникла похожая проблема при попытке отслеживать сеанс пользователя / идентификатор пользователя в многостраничной форме.

Я исправил это, добавив

.when ("/ q2 /: uid" в маршрутизации:

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

И добавил это как скрытое поле для передачи параметров между страницами веб-формы

<< input type = "hidden" обязательный ng-model = "formData.userid" ng-init = "formData.userid = uid" />

Я новичок в Angular, так что не уверен, что это лучшее из возможных решений, но сейчас мне кажется, что оно работает нормально.


0

Непосредственно назначьте значение модели в data-ng-valueатрибуте. Так как интерпретатор Angular не распознает скрытые поля как часть ngModel.

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

0

Я использую классический JavaScript, чтобы установить значение для скрытого ввода

$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

Ниже код будет работать для этого IFF в том же порядке, что и упомянутый выше. Убедитесь, что вы указали тип, а затем имя, ng-модель, ng-init, значение. Это оно.


0

Здесь я хотел бы поделиться своим рабочим кодом:

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


Не могли бы вы более объяснения, пожалуйста
JSmith

Конечно! Когда мы используем скрытое поле или текстовое поле с атрибутом display: none, пользователь не может ввести значение. В этом случае директива ng-init помогает установить значение для поля. Спасибо
J. Миддя

в посте я имел в виду Извините
JSmith
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.