AngularJS - ผูกปุ่มเรดิโอกับรุ่นที่มีค่าบูลีน


199

ฉันมีปัญหาผูกปุ่มเรดิโอกับวัตถุที่คุณสมบัติมีค่าบูลีน ฉันพยายามแสดงคำถามการสอบที่ดึงมาจากทรัพยากร $

HTML:

<label data-ng-repeat="choice in question.choices">
  <input type="radio" name="response" data-ng-model="choice.isUserAnswer" value="true" />
  {{choice.text}}
</label>

JS:

$scope.question = {
    questionText: "This is a test question.",
    choices: [{
            id: 1,
            text: "Choice 1",
            isUserAnswer: false
        }, {
            id: 2,
            text: "Choice 2",
            isUserAnswer: true
        }, {
            id: 3,
            text: "Choice 3",
            isUserAnswer: false
        }]
};   

ด้วยวัตถุตัวอย่างนี้คุณสมบัติ "isUserAnswer: true" จะไม่ทำให้ปุ่มตัวเลือกถูกเลือก ถ้าฉันใส่แค็ปซูลค่าบูลีนในเครื่องหมายคำพูดมันใช้งานได้

JS:

$scope.question = {
    questionText: "This is a test question.",
    choices: [{
            id: 1,
            text: "Choice 1",
            isUserAnswer: "false"
        }, {
            id: 2,
            text: "Choice 2",
            isUserAnswer: "true"
        }, {
            id: 3,
            text: "Choice 3",
            isUserAnswer: "false"
        }]
};   

น่าเสียดายที่บริการ REST ของฉันถือว่าคุณสมบัติเป็นบูลีนและมันจะเป็นการยากที่จะเปลี่ยนการทำให้เป็นอันดับ JSON เพื่อสรุปค่าเหล่านั้นในราคา มีวิธีอื่นในการตั้งค่าการโยงโมเดลโดยไม่เปลี่ยนโครงสร้างของโมเดลของฉันหรือไม่?

นี่คือ jsFiddle ที่แสดงวัตถุที่ไม่ทำงานและที่ทำงาน

คำตอบ:


376

วิธีการที่ถูกต้องใน Angularjs คือการใช้ng-valueสำหรับค่าที่ไม่ใช่สตริงของแบบจำลอง

แก้ไขรหัสของคุณเช่นนี้:

<label data-ng-repeat="choice in question.choices">
  <input type="radio" name="response" data-ng-model="choice.isUserAnswer" data-ng-value="true" />
  {{choice.text}}
</label>

การอ้างอิง: ตรงจากปากม้า


12
ต้องการเพิ่มหมายเหตุด้านที่สำคัญ: ng-value จะต้องมีค่าโดยไม่ต้องใช้เครื่องหมายปีกกา {{}} ตัวอย่าง: ng-value = "choice2.id" vs value = "{{choice2.id}}"
Andi

ใช่นั่นถูกต้องเนื่องจาก ng-value ถูกประเมินในขอบเขตนั้น
kumarharsh

@ Andi ขอบคุณสำหรับบันทึกด้านนี้มันช่วยฉันแก้จุดบกพร่องบางครั้ง!
Roy Milder

3
คุณหมายถึงdata- prefix ที่ฉันคิดว่า ... data- prefix นั้นคือการทำให้ HTML ใช้งานได้ (แม้ว่าจะไม่มีเบราว์เซอร์ที่ทันสมัยทั้งหมดก็จัดการ HTML ได้อย่างถูกต้อง)
kumarharsh

6
ฉันรู้ว่าโพสต์นั้นค่อนข้างเก่า แต่ตอนนี้ฉันมีปัญหาเดียวกัน แต่เมื่อฉันใช้วิธีแก้ปัญหาของคุณและเปลี่ยนปุ่มตัวเลือกทั้งหมดที่เคยเลือกนั้นเป็นจริงและพวกเขาจะไม่เปลี่ยนกลับเป็นเท็จ มีวิธีแก้ปัญหาสำหรับเรื่องนี้หรือไม่? (ปัญหายังมีอยู่ในซอของ OP)
Dominik G

21

นั่นเป็นวิธีการแปลก ๆ isUserAnswerด้วย คุณจะส่งทั้งสามตัวเลือกกลับไปที่เซิร์ฟเวอร์ซึ่งมันจะวนซ้ำในแต่ละการตรวจสอบisUserAnswer == trueใช่หรือไม่ ถ้าเป็นเช่นนั้นคุณสามารถลอง:

http://jsfiddle.net/hgxjv/4/

HTML:

<input type="radio" name="response" value="true" ng-click="setChoiceForQuestion(question1, choice)"/>

JavaScript:

$scope.setChoiceForQuestion = function (q, c) {
    angular.forEach(q.choices, function (c) {
        c.isUserAnswer = false;
    });

    c.isUserAnswer = true;
};

หรือมิฉะนั้นฉันขอแนะนำให้คุณเปลี่ยนแทค

http://jsfiddle.net/hgxjv/5/

<input type="radio" name="response" value="{{choice.id}}" ng-model="question1.userChoiceId"/>

ด้วยวิธีนี้คุณสามารถส่ง{{question1.userChoiceId}}กลับไปที่เซิร์ฟเวอร์


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

2
อาจริง คุณสามารถแก้ไขได้โดยใช้ngCheckedยกเว้นคุณจะต้องแยกตัวออกจากการใช้จริง / เท็จเป็นสตริง คุณสามารถทำได้ไหม? jsfiddle.net/hgxjv/6
Langdon

3
ใช่มันใช้งานได้! ฉันเคยลองใช้ ngChecked มาก่อน แต่ไม่ได้ลบแอตทริบิวต์ ngModel ไม่ทำงานกับการกำหนดค่านั้นและฉันคิดว่าเป็นเพราะ ngChecked ไม่สามารถใช้งานร่วมกับปุ่มตัวเลือก การลบแอททริบิว ngModel และการใช้ ngChecked และการโยง ngClick ไปยังฟังก์ชัน setChoiceForQuestion ของคุณจะได้สิ่งที่ฉันพยายามทำ ขอขอบคุณสำหรับความช่วยเหลือของคุณ!
peteallen

10
 <label class="rate-hit">
     <input type="radio" ng-model="st.result" ng-value="true" ng-checked="st.result">
     Hit
 </label>
 &nbsp;&nbsp;
 <label class="rate-miss">
     <input type="radio" ng-model="st.result" ng-value="false" ng-checked="!st.result">
     Miss
 </label>

ฉันคิดว่ามันใช้งานได้เพียงเพราะtrueประเมินเป็นจริง หากng-valueเป็นสตริงตัวอย่างเช่นไม่ใช่การอ้างอิงถึงบางสิ่ง$scopeคุณจะต้องใส่สตริงนั้นในเครื่องหมายคำพูด นั่นเป็นกรณีสำหรับฉัน
Jason Swett

นี่คือคำตอบที่ดีที่สุดสำหรับฉัน! ขอบคุณ Ronel!
Gisway

ไม่จำเป็นต้องตรวจสอบกับ ng ที่นี่ตราบใดที่ ng-model ถูกกำหนด
Nico Westerdale

7

ฉันพยายามเปลี่ยนvalue="true"ไปng-value="true"และดูเหมือนว่าจะทำงาน

<input type="radio" name="response2" data-ng-model="choice.isUserAnswer" ng-value="true" />

นอกจากนี้ยังจะได้รับปัจจัยการผลิตทั้งในการทำงานในตัวอย่างของคุณคุณจะต้องให้ชื่อที่แตกต่างกันไปในแต่ละอินพุต - เช่นresponseควรจะเป็นและresponse1response2


1
ไม่ชื่อสามารถเหมือนกัน
Kumarharsh


0

วิธีการตั้งค่าวิทยุของคุณในซอ - การแบ่งปันโมเดลเดียวกัน - จะทำให้เฉพาะกลุ่มสุดท้ายที่จะแสดงวิทยุที่ตรวจสอบแล้วหากคุณตัดสินใจที่จะเสนอราคาค่าความจริงทั้งหมด แนวทางที่มั่นคงยิ่งขึ้นจะเกี่ยวข้องกับการให้แบบจำลองของแต่ละกลุ่มแต่ละกลุ่มและตั้งค่าเป็นคุณลักษณะเฉพาะของวิทยุเช่น id:

$scope.radioMod = 1;
$scope.radioMod2 = 2;

นี่คือการแสดงของ html ใหม่:

<label data-ng-repeat="choice2 in question2.choices">
            <input type="radio" name="response2" data-ng-model="radioMod2" value="{{choice2.id}}"/>
                {{choice2.text}}
        </label>

และเล่นซอ


0

หากคุณใช้ตัวแปรบูลีนเพื่อผูกปุ่มตัวเลือก โปรดดูรหัสตัวอย่างด้านล่าง

<div ng-repeat="book in books"> 
<input type="radio" ng-checked="book.selected"  
ng-click="function($event)">                        
</div>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.