简体   繁体   English

Knockout.js:单选按钮第一次单击不显示在3.0中,显示在2.1-2.3中

[英]Knockout.js : radio button first click does not show in 3.0, shows in 2.1-2.3

Fiddle : http://jsfiddle.net/pr5YQ/7/ 小提琴: http//jsfiddle.net/pr5YQ/7/

I'm having what appears to be a relatively common problem with Knockout.js - whenever a radio button is first selected, the value in the object model updates, but the radio button itself does not show the selection. 我遇到了Knockout.js的一个相对常见的问题 - 每当首次选择单选按钮时,对象模型中的值会更新,但单选按钮本身不会显示选择。 Upon second selection, the item shows the check. 在第二次选择时,该项目显示检查。

The interesting thing is that Knockout version 2 works correctly! 有趣的是Knockout版本2正常工作! It's only Knockout version 3 that has an issue. 只有Knockout版本3才有问题。 Within the fiddle, switch to any version of Knockout 2 and the form works as needed. 在小提琴中,切换到任何版本的Knockout 2,表单根据需要工作。

I have checked to see if there are any issues with the data type I'm setting as the value (they're both numbers, which should be fine) and the name/value setup appears to be correct. 我已经检查了数据类型是否存在任何问题我将其设置为值(它们都是数字,应该没问题)并且名称/值设置似乎是正确的。 I would expect that, if I had failed to do either of the above, then the first click failure would show in all versions of Knockout. 我希望如果我没有做到上述任何一个,那么第一次点击失败将显示在所有版本的Knockout中。

Here's a snippet of the data model I have : 这是我所拥有的数据模型的片段:

        "Question_Ref": 1,
            "Question_Text": "Question 1",
            "Response_Ref": -1,
            "Response_Text": "",
            "Selected_Answer_Ref": -1,
            "Answers": [{
            "Answer_Ref": 1,
                "Answer_Text": "Yes",
                "Answer_Fails": false
        }, {
            "Answer_Ref": 2,
                "Answer_Text": "No",
                "Answer_Fails": false
        }]

And here's how I take the data object itself and attach the necessary KO bindings : 这是我如何获取数据对象本身并附加必要的KO绑定:

function AttachKOObjectsOnQuestion(question) {
    question.Selected_Answer_Ref_KO = ko.observable(question.Selected_Answer_Ref);
    question.Show_Response_KO = ko.computed({
        read: function () {
            if (!question.Selected_Answer_Ref_KO()) return null;
            if (question.Selected_Answer_Ref_KO() < 0) return null;
            for (selAnswerCount = 0; selAnswerCount < this.Answers.length; selAnswerCount++) {
                var answer = this.Answers[selAnswerCount];
                if (answer.Answer_Ref === this.Selected_Answer_Ref_KO()) {
                    return answer.Answer_Fails;
                }
            }
            return null
        },
        write: function (value) {},
        owner: question
    });
    var answerCount;
    for (answerCount = 0; answerCount < question.Answers.length; answerCount++) {
        AttachKOObjectsOnQuestionAnswer(question, question.Answers[answerCount]);
    }
}

function AttachKOObjectsOnQuestionAnswer(question, answer) {
    answer.ParentQuestion = question;
    answer.Selected_Answer_Ref_KO = ko.computed({
        read: function () {
            return answer.ParentQuestion.Selected_Answer_Ref_KO();
        },
        write: function (value) {
            var selectedAnswer = parseInt(value, 10);
            answer.ParentQuestion.Selected_Answer_Ref_KO(selectedAnswer);
        },
        owner: answer
    });
}

And here's the relevant setup of the radio buttons : 以下是单选按钮的相关设置:

<table cellpadding="0" cellspacing="0">
    <tbody data-bind="foreach: Answers">
        <tr>
            <td>
                <input type="radio" data-bind="attr: { value: Answer_Ref, name: ParentQuestion.Question_Ref }, checked: Selected_Answer_Ref_KO, click: hideValidators" />
            </td>
            <td>
                <span data-bind="text: Answer_Text"></span>
            </td>
        </tr>
    </tbody>
</table>

This is both my first usage of Knockout and of JSON, so feel free to offer critiques. 这是我第一次使用Knockout和JSON,所以请随意提出批评。 Thank you! 谢谢!

Your problem is that your checked binding is incorrect on the radiobutton. 您的问题是您的checked绑定在radiobutton上是不正确的。 You're trying to bind checked to a property on your answer called Selected_Answer_Ref_KO . 您正尝试将checked绑定到名为Selected_Answer_Ref_KO的答案的属性。 However, that you have added that object to the Question, not the Answer. 但是,您已将该对象添加到问题,而不是答案。

To fix this problem, just change your checked binding to checked: $parent.Selected_Answer_Ref_KO . 要解决此问题,只需将checked绑定更改为已checked: $parent.Selected_Answer_Ref_KO I have updated your fiddle with this change and the selection work on the first click for me. 我已经更新了你的小提琴这个改变和第一次点击选择工作对我来说。 You can find that update at http://jsfiddle.net/pr5YQ/5/ . 您可以在http://jsfiddle.net/pr5YQ/5/找到该更新。

This was answered by Adam Rackis on Facebook. Adam Rackis在Facebook上回答这个问题。

Knockout 3 uses strict comparison, and I had not realized that anything in an input value is a string. Knockout 3使用严格的比较,我没有意识到输入值中的任何内容都是字符串。 As a result, the radio button value (a string) never matched my data model's value (a number). 结果,单选按钮值(字符串)从未匹配我的数据模型的值(数字)。

Worse, I missed that the documentation mentions that you can use the checkedValue binding to set values that are not strings. 更糟糕的是,我错过了文档提到您可以使用checkedValue绑定来设置非字符串的值。 That is the correct fix for my problem, as I want my data model's current type to remain a number. 这是我的问题的正确解决方案,因为我希望我的数据模型的当前类型保持为数字。

<input type="radio" data-bind="attr: { name: ParentQuestion.Question_Ref }, checkedValue : Answer_Ref, checked: Selected_Answer_Ref_KO, click: hideValidators" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM