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>

หากฉันกดปุ่มส่งจะไม่มีการส่งค่าใด ๆ ไปยังเซิร์ฟเวอร์ ถ้าฉันเปลี่ยนฟิลด์อินพุตให้พิมพ์ "text" มันทำงานได้ตามที่คาดไว้ ข้อสันนิษฐานของฉันคือเขตข้อมูลที่ซ่อนอยู่ไม่ได้บรรจุจริง ๆ ในขณะที่เขตข้อมูลข้อความจะแสดงเนื่องจากการผูกสองทาง

แนวคิดใดบ้างที่ฉันสามารถส่งฟิลด์ที่ซ่อนอยู่ซึ่งบรรจุโดย AngularJS


4
อืม ... วิธีการพิมพ์ข้อความdisplay: none;ล่ะ? มันน่าเกลียดมาก เชิงมุมละเว้นองค์ประกอบที่ซ่อนอยู่
tymeJV

ใส่นั่นเป็นคำตอบ @tymeJV!
Jeroen Ingelbrecht

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' เพื่อผูกนิพจน์กับแอตทริบิวต์ value ของอินพุต คำสั่งนี้ควรใช้กับอินพุตของวิทยุหรือช่องทำเครื่องหมาย แต่ทำงานได้ดีกับอินพุตที่ซ่อนอยู่

นี่คือวิธีแก้ปัญหาโดยใช้ ng-value:

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

นี่คือซอที่ใช้ ng-value พร้อมอินพุตที่ซ่อนอยู่: http://jsfiddle.net/6SD9N


น่ากลัว ขอบคุณมาก. ฉันเกือบจะไปซ่อนที่ Textfield แต่ตอนนี้ฉันรู้สึกว่ามันเป็นวิธีแก้ปัญหาที่ดี
คริสเตียน

22
ยิ่งใหญ่ และคุณยังสามารถใช้ ng-value = "modelName" เพื่อทำมันโดยไม่ต้องใส่เครื่องหมายวงเล็บ
โจนาธาน

2
ถูกต้องเนื่องจาก Angular 1.2 คุณสามารถใช้ ng-value เพื่อผูกนิพจน์กับแอตทริบิวต์ value ได้คำตอบล่าสุด
มิคเคล

คุณต้องการฟิลด์ที่ซ่อนอยู่จริงๆอีกต่อไปเมื่อคุณใช้ AngularJS บน ngSubmit คุณกดปุ่มควบคุมข้อมูลทั้งหมดของคุณจะมองเห็นได้อย่างสมบูรณ์สำหรับการเข้าถึงและคุณส่งข้อมูลทั้งหมดผ่านบริการ $ http
mtpultz

3
ขอบคุณมาก. ความจริงที่ว่า ng-model ไม่สามารถใช้สำหรับอินพุตที่ซ่อนอยู่ควรจัดทำเป็นเอกสารใน AngularJS IMO
yoonchee

47

คุณสามารถใช้type=textและdisplay:none;เนื่องจาก Angular ละเว้นองค์ประกอบที่ซ่อนอยู่ อย่างที่ OP บอกว่าปกติคุณจะไม่ทำสิ่งนี้ แต่นี่เป็นกรณีพิเศษ

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

ขอบคุณ! ฉันคิดไปในทิศทางเดียวกัน แต่ฉันแค่ต้องการ {{}} วิธีแก้ปัญหาจาก Mickael
คริสเตียน

1
วิธีแก้ปัญหาที่ฉลาด / ฉลาด
ImranNaqvi

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

แต่วิธีการแก้ปัญหาของ 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 มันจะอัพเดตโมเดล binded เช่นกัน


มีใครอีกบ้างที่มีปัญหาในการใช้งานโซลูชันนี้หรือไม่ ปัญหาคือว่าพารามิเตอร์ ngModel ไม่ได้ถูกกำหนดเมื่อมีการแยกวิเคราะห์และดำเนินการดังนั้นจึงไม่ได้เพิ่ม $ watch
icfantv

ตกลง. ดูเหมือนว่าปัญหาคือพารามิเตอร์ที่สี่ ngModel เป็นวัตถุในขณะที่ตัวอย่างที่อ้างอิงจากลิงก์ที่ sapiensworks จะดึงค่าสตริงของแอตทริบิวต์ ng-model ผ่าน attr ['ngModel'] จากนั้นส่งต่อไปยังนาฬิกา ฉันสามารถยืนยันได้ว่าการเปลี่ยนแปลงนี้แก้ไขปัญหาของนาฬิกาได้
icfantv

มีปัญหาอื่นที่นี่ jQuery ไม่ดำเนินการเหตุการณ์การเปลี่ยนแปลงเมื่อคุณเปลี่ยนค่าของฟิลด์อินพุตที่ซ่อนโดยทางโปรแกรม ดังนั้นถ้าฉันพูด $ (hidden_input_elt) .val ("snoopy") ฉันต้องเพิ่ม. change () เพื่อให้เหตุการณ์การเปลี่ยนแปลงเปลี่ยนไป ปัญหาเกี่ยวกับเรื่องนี้คือ Angular จะบ่นเกี่ยวกับ $ scope ข้างบน () เนื่องจากมีการใช้งาน $ อยู่แล้วกำลังดำเนินการอยู่ ทางออกที่นี่คือการลบขอบเขต $ $ ใช้ในฟังก์ชั่นการเปลี่ยนแปลงข้างต้นและเพียงแค่เรียก 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

อัปเดตคำตอบของ @tymeJV เช่น:

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

0

ฉันประสบปัญหาเดียวกันฉันต้องส่งกุญแจจาก jsp ของฉันไปที่จาวาสคริปต์จริง ๆ ใช้เวลาประมาณ 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

ในกรณีที่บางคนยังคงดิ้นรนกับเรื่องนี้ฉันมีปัญหาคล้ายกันเมื่อพยายามติดตามเซสชันผู้ใช้ / หมายเลขผู้ใช้บนแบบฟอร์มหลายรายการ

ฉันแก้ไขแล้วโดยการเพิ่ม

. เมื่อ ("/ q2 /: uid" ในการกำหนดเส้นทาง:

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

และเพิ่มสิ่งนี้เป็นฟิลด์ที่ซ่อนอยู่เพื่อส่งผ่าน params ระหว่างหน้าเว็บฟอร์ม

<< ประเภทอินพุต = "ซ่อน" จำเป็นต้องมี ng-model = "formData.userid" ng-init = "formData.userid = uid" />

ฉันใหม่กับแองกูลาร์ดังนั้นไม่แน่ใจว่ามันเป็นทางออกที่ดีที่สุด แต่ดูเหมือนว่ามันใช้ได้สำหรับฉัน


0

กำหนดค่าให้กับแบบจำลองในdata-ng-valueแอตทริบิวต์โดยตรง เนื่องจากตัวแปลเชิงมุมไม่รู้จักฟิลด์ที่ซ่อนอยู่ในฐานะเป็นส่วนหนึ่งของ ngModel

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

0

ฉันใช้จาวาสคริปต์คลาสสิกเพื่อตั้งค่าเป็นอินพุตที่ซ่อนอยู่

$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, มูลค่า แค่นั้นแหละ.


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


ช่วยอธิบายเพิ่มเติม
หน่อยได้ไหม

แน่นอน! เมื่อเราใช้ฟิลด์ที่ซ่อนอยู่หรือฟิลด์ข้อความที่มี display: none attribute ผู้ใช้จะไม่สามารถป้อนค่า ในกรณีนั้นคำสั่ง ng-init ช่วยในการตั้งค่าสำหรับฟิลด์ ขอบคุณ
J. Middya

ในโพสต์ฉันหมายถึงขออภัย
JSmith
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.