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.