AngularJS не надсилає значення прихованого поля


192

Для конкретного випадку використання я повинен подати єдину форму "старим способом". Значить, я використовую форму з action = "". Відповідь передається потоково, тому я не перезавантажую сторінку. Я цілком усвідомлюю, що типовий додаток AngularJS не надсилає форму таким чином, але поки що у мене немає іншого вибору.

Це сказав, що я намагався заселити кілька прихованих полів з кутових:

<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;,? Це потворне тхо. Кутова ігнорує приховані елементи.
tymeJV

поставте це як відповідь @tymeJV!
Jeroen Ingelbrecht

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

Відповіді:


287

Ви не можете використовувати подвійне зв’язування із прихованим полем. Рішення полягає у використанні дужок:

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

EDIT: Дивіться цю тему на github: https://github.com/angular/angular.js/pull/2574

Редагувати:

Оскільки Angular 1.2, ви можете використовувати директиву 'ng-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-модель не може бути використана для прихованого введення, повинен бути задокументований в IMO AngularJS.
yoonchee

47

Ви завжди можете використовувати type=textі display:none;так Кутові ігнорує приховані елементи. Як каже ОП, ви зазвичай цього не робили, але це здається особливим випадком.

<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
Хороший момент ... Я б краще це зробив тільки в контролері наступного разу
meffect


Nooo. в циклі він створює багато проблем і присвоює останнє значення всім, 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, може бути кращим, оскільки прихований прихований сигнал не змінює події в 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'], а потім передає це в годинник. Я можу підтвердити, що внесення цієї зміни усуває проблему перегляду.
icfantv

Тут є ще одне питання. jQuery не запускає подію зміни, коли ви програматично змінюєте значення прихованого поля введення. Тож якщо я скажу $ (hidden_input_elt) .val ("snoopy"), я повинен також додати .change (), щоб викликати запуск зміни. Проблема в цьому полягає в тому, що Angular поскаржиться на вищезазначений $ range.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! ІД = 3.

З найкращими побажаннями


0

На випадок, якщо хтось із цим все ще бореться, у мене виникли подібні проблеми, коли я намагався відслідковувати сеанс користувача / userid у багатосторінковій формі

Я це виправив, додавши

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

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

І додав це як приховане поле для передачі парам між сторінками веб-форми

<< тип введення = "приховано" потрібно ng-model = "formData.userid" ng-init = "formData.userid = uid" />

Я новачок у Angular, тому не впевнений, що це найкраще можливе рішення, але, здається, зараз це нормально для мене


0

Безпосередньо призначте значення data-ng-valueатрибуту моделі . Оскільки Angular interpreter не розпізнає приховані поля як частину 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

Звичайно! Коли ми використовуємо приховане поле або текстове поле з відображенням: жоден атрибут, користувач не може ввести значення. У цьому випадку директива ng-init допомагає встановити значення для поля. Спасибі
Дж. Міддя

в дописі я мав на увазі Вибачте
JSmith
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.