AngularJS - Liên kết các nút radio với các mô hình có giá trị boolean


199

Tôi đang gặp vấn đề liên kết các nút radio với một đối tượng có thuộc tính có giá trị boolean. Tôi đang cố gắng hiển thị các câu hỏi thi lấy từ tài nguyên $.

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

Với đối tượng ví dụ này, thuộc tính "isUserAnswer: true" không làm cho nút radio được chọn. Nếu tôi gói gọn các giá trị boolean trong dấu ngoặc kép, nó hoạt động.

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

Thật không may, dịch vụ REST của tôi coi thuộc tính đó là boolean và sẽ rất khó để thay đổi tuần tự hóa JSON để gói gọn các giá trị đó trong dấu ngoặc kép. Có cách nào khác để thiết lập liên kết mô hình mà không thay đổi cấu trúc mô hình của tôi không?

Đây là jsFiddle hiển thị các đối tượng không hoạt động và làm việc

Câu trả lời:


376

Cách tiếp cận đúng trong Angularjs là sử dụng ng-valuecho các giá trị không phải là chuỗi của các mô hình.

Sửa đổi mã của bạn như thế này:

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

Tham khảo: Thẳng từ miệng ngựa


12
chỉ muốn thêm một ghi chú bên quan trọng: ng-value phải có giá trị mà không có dấu ngoặc nhọn {{}} Ví dụ: ng-value = "Choice2.id" vs value = "{{Choice2.id}}"
Andi

Vâng, điều đó là chính xác, vì giá trị ng được đánh giá trong phạm vi đó
kumarharsh

@Andi cảm ơn vì lưu ý bên này, nó đã giúp tôi tiết kiệm thời gian gỡ lỗi!
Roy Milder

3
Ý bạn là tiền tố dữ liệu tôi nghĩ ... Tiền tố dữ liệu là làm cho HTML hợp lệ (mặc dù không có tất cả các trình duyệt hiện đại xử lý HTML chính xác)
kumarharsh 19/12/14

6
Tôi biết bài viết khá cũ nhưng bây giờ tôi đã gặp vấn đề tương tự. Nhưng khi tôi sử dụng giải pháp của bạn và thay đổi các nút radio, tất cả những gì đã được chọn là đúng và chúng không chuyển về sai. đó có phải là cách giải quyết? (vấn đề cũng tồn tại trong Fiddle của OP)
Dominik G

21

Đó là một cách tiếp cận kỳ lạ với isUserAnswer. Bạn có thực sự sẽ gửi cả ba lựa chọn trở lại máy chủ nơi nó sẽ lặp qua từng lựa chọn isUserAnswer == truekhông? Nếu vậy, bạn có thể thử điều này:

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

Ngoài ra, tôi khuyên bạn nên thay đổi chiến thuật của mình:

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

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

Bằng cách đó bạn chỉ có thể gửi {{question1.userChoiceId}}lại cho máy chủ.


Cám ơn phản hồi của bạn. Tôi biết giải pháp thứ hai của bạn là lý tưởng; tuy nhiên, ứng dụng thực sự hỗ trợ nhiều loại câu hỏi, bao gồm cả câu hỏi "kiểm tra tất cả các câu hỏi áp dụng" - do đó lý do cho giá trị được lưu trữ trên mỗi lựa chọn. Từ những gì tôi có thể nói, giải pháp đầu tiên của bạn hoạt động để cập nhật mô hình sau khi lựa chọn được thực hiện, nhưng không phải để hiển thị mô hình được truy xuất từ ​​máy chủ với lựa chọn đã được thực hiện.
peteallen

2
À, đúng rồi. Bạn có thể giải quyết điều đó bằng cách sử dụng ngChecked, ngoại trừ bạn sẽ phải tách ra khỏi việc sử dụng đúng / sai dưới dạng chuỗi. Bạn có thể làm điều đó? jsfiddle.net/hgxjv/6
Langdon

3
Vâng, nó hoạt động! Tôi đã thử sử dụng ngChecked trước đây, nhưng chưa xóa thuộc tính ngModel. Nó không hoạt động với cấu hình đó và tôi đã cho rằng đó là do ngChecked không tương thích với các nút radio. Xóa thuộc tính ngModel và sử dụng ngChecked và ràng buộc ngClick vào hàm setChoiceForQuestion của bạn đạt được những gì tôi đang cố gắng thực hiện. Cảm ơn sự giúp đỡ của bạn!
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>

Tôi nghĩ rằng điều này chỉ hoạt động vì trueđánh giá là đúng. Nếu ng-valueví dụ của bạn là một chuỗi và không phải là một tham chiếu đến một cái gì đó $scope, bạn sẽ phải đặt chuỗi đó trong dấu ngoặc kép. Đó là trường hợp của tôi.
Jason Swett

Đây là câu trả lời tốt nhất cho tôi! Cảm ơn, Ronel!
Gisway

ng-kiểm tra không cần thiết ở đây miễn là mô hình ng được xác định
Nico Westerdale

7

Tôi đã cố gắng thay đổi value="true"để ng-value="true", và có vẻ như để làm việc.

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

Ngoài ra, để làm cho cả hai đầu vào hoạt động trong ví dụ của bạn, bạn phải đặt tên khác nhau cho mỗi đầu vào - ví dụ: responsenên trở thành response1response2.


1
Không, tên có thể giống nhau.
kumarharsh


0

Cách radio của bạn được thiết lập trong fiddle - chia sẻ cùng một mô hình - sẽ chỉ khiến nhóm cuối cùng hiển thị radio đã kiểm tra nếu bạn quyết định trích dẫn tất cả các giá trị trung thực. Một cách tiếp cận vững chắc hơn sẽ liên quan đến việc cung cấp cho các nhóm riêng lẻ mô hình riêng của họ và đặt giá trị làm thuộc tính duy nhất của radio, chẳng hạn như id:

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

Đây là một đại diện của html mới:

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

Và một câu đố.


0

nếu bạn đang sử dụng biến boolean để liên kết nút radio. vui lòng tham khảo mã mẫu bên dưới

<div ng-repeat="book in books"> 
<input type="radio" ng-checked="book.selected"  
ng-click="function($event)">                        
</div>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.