AngularJS - Mengikat tombol radio ke model dengan nilai boolean

199

Saya mengalami masalah pengikatan tombol radio ke objek yang propertinya memiliki nilai boolean. Saya mencoba menampilkan pertanyaan ujian yang diambil dari sumber daya $.

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
        }]
};   

Dengan objek contoh ini, properti "isUserAnswer: true" tidak menyebabkan tombol radio dipilih. Jika saya merangkum nilai boolean dalam tanda kutip, itu berfungsi.

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"
        }]
};   

Sayangnya layanan REST saya memperlakukan properti itu sebagai boolean dan akan sulit untuk mengubah serialisasi JSON untuk merangkum nilai-nilai tersebut dalam tanda kutip. Apakah ada cara lain untuk mengatur model yang mengikat tanpa mengubah struktur model saya?

Inilah jsFiddle yang menunjukkan objek yang tidak bekerja dan bekerja

Peteallen
sumber

Jawaban:

376

Pendekatan yang benar dalam Angularjs adalah untuk digunakan ng-valueuntuk nilai-nilai non-string model.

Ubah kode Anda seperti ini:

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

Ref: Langsung dari mulut kuda

kumarharsh
sumber
12
hanya ingin menambahkan catatan penting: ng-nilai harus memiliki nilai tanpa kurung kurawal {{}} Contoh: ng-value = "choice2.id" vs value = "{{choice2.id}}"
Andi
Ya, itu benar, karena nilai-
n
@Andi terima kasih atas catatan samping ini, ini menghemat waktu saya untuk debug!
Roy Milder
3
Anda berarti data- awalan saya pikir ... The data- prefix adalah untuk membuat HTML yang valid (meskipun tanpa yang juga semua browser modern menangani HTML dengan benar)
kumarharsh
6
Saya tahu posnya sudah cukup lama tetapi saya mendapat masalah yang sama sekarang. Tetapi ketika saya menggunakan solusi Anda dan mengubah tombol radio semua yang pernah dipilih adalah benar dan mereka tidak beralih kembali ke false. Apakah ada solusi untuk ini? (Masalah juga ada di OP's Fiddle)
Dominik G
21

Itu pendekatan yang aneh dengan isUserAnswer. Apakah Anda benar-benar akan mengirim ketiga pilihan kembali ke server di mana ia akan mengulangi masing-masing memeriksa isUserAnswer == true? Jika demikian, Anda dapat mencoba ini:

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;
};

Atau, saya sarankan mengubah taktik Anda:

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

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

Dengan begitu Anda bisa mengirim {{question1.userChoiceId}}kembali ke server.

Langdon
sumber
Terimakasih atas tanggapan Anda. Saya tahu solusi kedua Anda ideal; namun, aplikasi ini sebenarnya mendukung beberapa jenis pertanyaan, termasuk pertanyaan "periksa semua yang berlaku" - karenanya alasan nilai disimpan pada setiap pilihan. Dari apa yang saya tahu, solusi pertama Anda berfungsi untuk memperbarui model setelah pemilihan dibuat, tetapi tidak untuk menampilkan model yang diambil dari server dengan pilihan yang sudah dibuat.
peteallen
2
Ah benar Anda dapat mengatasinya dengan menggunakan ngChecked, kecuali Anda harus melepaskan diri dari menggunakan true / false sebagai string. Bisakah kamu melakukan itu? jsfiddle.net/hgxjv/6
Langdon
3
Ya itu berhasil! Saya telah mencoba menggunakan ngChecked sebelumnya, tetapi belum menghapus atribut ngModel. Itu tidak berfungsi dengan konfigurasi itu, dan saya berasumsi itu karena ngChecked tidak kompatibel dengan tombol radio. Menghapus atribut ngModel dan menggunakan ngChecked dan mengikat ngClick ke fungsi setChoiceForQuestion Anda mencapai apa yang saya coba lakukan. Terima kasih untuk bantuannya!
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>
Ronel Gonzales
sumber
Saya pikir ini hanya berhasil karena truedinilai benar. Jika Anda ng-valueadalah string, misalnya, dan bukan referensi untuk sesuatu di dalamnya $scope, Anda harus meletakkan string itu dalam tanda kutip. Itulah yang terjadi pada saya.
Jason Swett
Ini jawaban terbaik untukku! Terima kasih, Ronel!
Gisway
ng-checked tidak diperlukan di sini selama ng-model didefinisikan
Nico Westerdale
7

Aku mencoba mengubah value="true"ke ng-value="true", dan tampaknya bekerja.

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

Juga, untuk mendapatkan kedua input berfungsi dalam contoh Anda, Anda harus memberikan nama yang berbeda untuk setiap input - misalnya responseharus menjadi response1dan response2.

Seung
sumber
1
Tidak, nama bisa sama.
kumarharsh
0

Cara radio Anda diatur dalam biola - berbagi model yang sama - hanya akan menyebabkan kelompok terakhir menampilkan radio yang dicentang jika Anda memutuskan untuk mengutip semua nilai kebenaran. Pendekatan yang lebih solid akan melibatkan pemberian masing-masing kelompok model mereka sendiri, dan menetapkan nilai sebagai atribut unik dari radio, seperti id:

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

Berikut ini adalah representasi dari html baru:

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

Dan biola.

rGil
sumber
0

jika Anda menggunakan variabel boolean untuk mengikat tombol radio. silakan lihat kode contoh di bawah ini

<div ng-repeat="book in books"> 
<input type="radio" ng-checked="book.selected"  
ng-click="function($event)">                        
</div>
Sahitya M
sumber