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 2013

それを@tymeJVの答えにしてください!
Jeroen Ingelbrecht 2013

7
次の構文を使用して値をバインドします<input type="hidden" required ng-model="data.userid" ng-init="data.userid=pivot.id" /> 。これは適切な方法ではないかもしれませんが、私にとってはうまくいきます。
John P

回答:


287

非表示フィールドで二重バインディングを使用することはできません。解決策はブラケットを使用することです:

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

編集:githubでこのスレッドを参照してください:https//github.com/angular/angular.js/pull/2574

編集:

Angular 1.2以降、「ng-value」ディレクティブを使用して、式を入力の値属性にバインドできます。このディレクティブは入力ラジオまたはチェックボックスで使用する必要がありますが、非表示の入力でもうまく機能します。

ng-valueを使用したソリューションは次のとおりです。

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

これは、非表示の入力でng-valueを使用するフィドルです。http//jsfiddle.net/6SD9N


驚くばかり。どうもありがとう。私はほとんどテキストフィールドを非表示にするつもりでしたが、今はこれが素晴らしい回避策だと感じています。
クリスチャン

22
すごい。また、ng-value = "modelName"を使用して、ブラケットなしでそれを行うことができます。
ジョナサン

2
そうです、Angular 1.2以降では、ng-valueを使用して式をvalue属性にバインドできます。答えは最新です。
ミカエル2014年

AngularJSを使用するときに、本当に隠しフィールドが本当に必要ですか?ngSubmitでコントローラーにヒットすると、すべてのデータが完全にアクセス可能になり、$ httpサービスを介してすべて送信されます。
mtpultz 2014年

3
どうもありがとう。ng-modelが非表示の入力に使用できないという事実は、AngularJS IMOで文書化する必要があります。
ユンチー2015年

47

Angularは隠し要素を無視するので、いつでもa type=textを使用できdisplay:none;ます。OPが言うように、通常はこれを行いませんが、これは特別なケースのようです。

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

ありがとう!私は同じ方向に考えましたが、私は単にミカエルの{{}}ソリューションを好むだけでした。
クリスチャン

1
賢い/スマートなソリューション
ImranNaqvi 2016年

8

コントローラで:

$scope.entityId = $routeParams.entityId;

ビューで:

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

1
良い点...次回はコントローラーでのみこれを実行したいと思います
meffect

私はng-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 />

しかし、tycorJVによって提供されるソリューションは、非表示の入力がyycormanがこれに伝えたようにJavaScriptの変更イベントを起動しないため、より優れている可能性があります投稿でように、。

編集 変更イベントがトリガーされたときに新しい値をモデルに適用するようにディレクティブを変更したので、入力テキストとして機能します。

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

OK。問題は、4番目のパラメーターngModelがオブジェクトであるように見えますが、sapiensworksのリンクから参照されている例では、attr ['ngModel']を介してng-model属性の文字列値を取得し、それをウォッチに渡します。この変更により、時計の問題が解決したことを確認できました。
icfantv 2014

ここには別の問題があります。プログラムで非表示の入力フィールドの値を変更しても、jQueryは変更イベントを発生させません。したがって、$(hidden_​​input_elt).val( "snoopy")と言った場合、.change()も追加して、変更イベントを発生させる必要があります。これの問題は、上記の$ scope.apply()がすでに$ applyに含まれているため、Angularが上記の$ scope.apply()について不満を言うことです。ここでの解決策は、上記の変更関数で$ scope。$ applyを削除し、ngModel。$ setViewValue(...)を呼び出すだけです。
icfantv 14

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ólio1 criado com sucesso!ID = 3。

宜しくお願いします


0

誰かがまだこれで苦労している場合に備えて、複数ページのフォームでユーザーセッション/ユーザーIDを追跡しようとすると、同様の問題が発生しました

追加してそれを修正しました

ルーティングの.when( "/ q2 /:uid":

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

これを非表示フィールドとして追加し、Webフォームページ間でパラメーターを渡します

<< 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-model、ng-init、valueの順になっていることを確認してください。それでおしまい。


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

私は申し訳ありません
でした
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.