AngularJS - Powiązanie przycisków opcji z modelami o wartościach boolowskich


199

Mam problem z powiązaniem przycisków opcji z obiektem, którego właściwości mają wartości logiczne. Próbuję wyświetlić pytania egzaminacyjne pobrane z zasobu $.

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

W tym przykładowym obiekcie właściwość „isUserAnswer: true” nie powoduje wybrania przycisku opcji. Jeśli hermetyzuję wartości boolowskie w cudzysłowach, to działa.

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

Niestety moja usługa REST traktuje tę właściwość jako wartość logiczną i ciężko będzie zmienić serializację JSON, aby zawrzeć te wartości w cudzysłowach. Czy istnieje inny sposób skonfigurowania wiązania modelu bez zmiany struktury mojego modelu?

Oto jsFiddle pokazujący niedziałające i pracujące obiekty

Odpowiedzi:


376

Prawidłowe podejście w Angularjs polega na stosowaniu ng-valuew przypadku ciągów wartości modeli.

Zmodyfikuj kod w następujący sposób:

<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: Prosto z pyska konia


12
chciałem tylko dodać ważną notatkę: wartość-ng musi mieć wartość bez nawiasów klamrowych {{}} Przykład: ng-wartość = "choice2.id" vs wartość = "{{choice2.id}}"
Andi

Tak, to prawda, ponieważ wartość ng jest oceniana w tym zakresie
kumarharsh

@Andi dziękuję za tę notatkę dodatkową, dzięki czemu zaoszczędziłem trochę czasu na debugowanie!
Roy Milder

3
Masz na myśli prefiks danych ... Myślę, że prefiks danych ma sprawić, że HTML będzie poprawny (chociaż bez tego również wszystkie nowoczesne przeglądarki poprawnie obsługują HTML)
kumarharsh

6
Wiem, że post jest dość stary, ale teraz mam ten sam problem. Ale kiedy używam twojego rozwiązania i zmieniam przyciski opcji, wszystkie raz wybrane są prawdziwe i nie przełączają się ponownie na false. Czy jest na to rozwiązanie? (problem występuje również w skrzypcach OP)
Dominik G

21

To dziwne podejście isUserAnswer. Czy naprawdę zamierzasz odesłać wszystkie trzy opcje z powrotem do serwera, na którym będzie on przechodził przez każdą z nich w poszukiwaniu isUserAnswer == true? Jeśli tak, możesz spróbować:

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

Ewentualnie polecam zmianę halsu:

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

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

W ten sposób możesz po prostu odesłać z {{question1.userChoiceId}}powrotem na serwer.


Dzięki za twoją odpowiedź. Wiem, że twoje drugie rozwiązanie jest idealne; jednak aplikacja obsługuje wiele rodzajów pytań, w tym pytania „sprawdź wszystkie, które dotyczą” - stąd przyczyna przechowywania wartości dla każdego wyboru. Z tego, co mogę powiedzieć, twoje pierwsze rozwiązanie działa na aktualizację modelu po dokonaniu wyboru, ale nie na wyświetlaniu modelu pobranego z serwera z już dokonanym wyborem.
peteallen

2
Ach, prawda. Możesz rozwiązać ten problem, używając ngChecked, z wyjątkiem tego, że będziesz musiał zerwać z użyciem wartości true / false jako ciągów. Możesz to zrobić? jsfiddle.net/hgxjv/6
Langdon

3
Tak, to działa! Próbowałem wcześniej użyć ngChecked, ale nie usunąłem atrybutu ngModel. Nie działało z tą konfiguracją i założyłem, że było tak, ponieważ ngChecked nie był kompatybilny z przyciskami radiowymi. Usunięcie atrybutu ngModel i użycie ngChecked i powiązanie ngClick z funkcją setChoiceForQuestion osiąga to, co próbuję zrobić. Dziękuję za pomoc!
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>

Myślę, że to działa tylko dlatego, że trueocenia się na prawdę. Jeśli Twój ng-valueciąg znaków jest na przykład ciągiem, a nie odniesieniem do czegoś $scope, musisz wpisać ten ciąg w cudzysłów. Tak było w moim przypadku.
Jason Swett

To dla mnie najlepsza odpowiedź! Dzięki, Ronel!
Gisway

ng-sprawdzone nie jest tutaj potrzebne, dopóki zdefiniowany jest model ng
Nico Westerdale,

7

Próbowałem zmieniających value="true"się ng-value="true"i wydaje się do pracy.

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

Ponadto, aby oba wejścia działały w twoim przykładzie, musisz nadać każdemu z nich inną nazwę - np. responsePowinno się stać response1i response2.


1
Nie, nazwy mogą być takie same.
kumarharsh


0

Sposób skonfigurowania radia w skrzypcach - współdzielenie tego samego modelu - spowoduje, że tylko ostatnia grupa pokaże sprawdzone radio, jeśli zdecydujesz się zacytować wszystkie prawdziwe wartości. Bardziej solidne podejście będzie polegało na nadaniu poszczególnym grupom własnego modelu i ustawieniu wartości jako unikalnego atrybutu radiotelefonów, takiego jak id:

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

Oto reprezentacja nowego html:

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

I skrzypce.


0

jeśli używasz zmiennej boolean do powiązania przycisku opcji. zapoznaj się z przykładowym kodem

<div ng-repeat="book in books"> 
<input type="radio" ng-checked="book.selected"  
ng-click="function($event)">                        
</div>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.