使用计算将KnockoutJS绑定到单选按钮 [英] Binding KnockoutJS to Radio Button with computed

查看:86
本文介绍了使用计算将KnockoutJS绑定到单选按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含一系列答案的问题.每个答案都有一个名为isRight的布尔属性,它表示答案是否正确.

I have a question with an array of answers. Each answer has a boolean property called isRight, which represents whether the answer is...right.

我正在尝试为每个答案呈现一个单选按钮,并检查该答案是否正确.如果用户单击其他按钮,则答案将正确.

I'm trying to render a radio button for each answer, and have it be checked if that answer is right. If the user clicks a different button, that answer becomes correct.

我知道KO将checked属性绑定到一个值,并且仅当单选按钮的值与绑定值匹配时才会检查每个单选按钮;您不能直接绑定到isRight.

I understand that KO binds the checked property to a value, and each radio button will only be checked if the radio's value matches the bound value; you can't just bind directly to isRight.

我在问题本身上放了一个computedObservable,这应该做所有的事情.而且有效.问题是,我想订阅单选按钮的 change 事件,以查看何时选择了新答案(并发送ajax请求).我遇到的问题是,在更改处理程序中未更新ko绑定.似乎延迟处理程序会给我我想要的东西,但我希望有一个更直接的解决方案.

I put a computedObservable on the question itself, which should do all that. And it works. The problem is, I want to subscribe to the change event of the radio button, to see when a new answer is selected (and send an ajax request). The problem I'm having is that the ko binding is not updated in the change handler. It seems putting a delay in the handler will give me what I want, but I'd prefer a more direct solution.

看来,click事件运行得很好,但是即使单选按钮已经被选中,它也会在每次单击单选按钮时触发.

And it seems the click event works perfectly, but that'll fire each time a radio button is clicked, even if it's already checked.

有什么方法可以确保在change事件中更新绑定?当前代码是ko 2.0,我也尝试过2.1.

Is there any way to ensure that the binding is updated in the change event? Current code is ko 2.0, and I've also tried 2.1.

全小提琴

完整来源:

function Question() {
    this.name = "My Question";

    var i = 0;
    this.answers = ko.observableArray([
        new Answer(++i, "Answer 1", false),
        new Answer(++i, "Answer 2", true),
        new Answer(++i, "Answer 3", false)]);

    this.correctAnswer = ko.computed({
        read: function () {
            for (var i = 0, max = this.answers().length; i < max; i++)
                if (this.answers()[i].isRight())
                    return "answer-" + this.answers()[i].id();
        },
        write: function (newValue) {
            var newId = +newValue.split('-')[1];
            for (var i = 0, max = this.answers().length; i < max; i++)
                this.answers()[i].isRight(this.answers()[i].id() === newId);
        },
        owner: this
    });
}


function Answer(id, name, isRight) {
    this.id = ko.observable(id);
    this.name = ko.observable(name);
    this.isRight = ko.observable(isRight);
}

$(function () {
    ko.applyBindings(new Question());

    $(document).on("change", "input[type='radio']", function () {
        var answer = ko.dataFor(this);
        var isRight = answer.isRight();

        setTimeout(function () { alert("before = " + isRight + "  after = " + answer.isRight()); }, 1000);
    });
});


HTML:


HTML:

<div data-bind="text:name"></div>
<div data-bind="foreach:answers">
    <label>
        <span data-bind="text: name"></span>
        <input type="radio" name="uniqueQuestionName" data-bind="value: 'answer-' + id(), checked:$parent.correctAnswer" />
    </label>
    <br />
</div>

推荐答案

除非您有特定的原因订阅"change"事件,否则您可能要考虑使用

Unless you have a specific reason to subscribe to the "change" event, you might want to consider using a manual subscription to an observable that is changing. This way you can be notified whenever the actual data is changed.

以下是使用稍有不同的方法的示例: http://jsfiddle.net/rniemeyer/FvZXj/.它使用一个函数来处理该值的设置,该值将当前答案作为第一个参数传递.然后,它将使用它来正确设置isRight和您可以订阅的可观察的correctAnswer.

Here is a sample that uses a slightly different approach: http://jsfiddle.net/rniemeyer/FvZXj/. It uses a function to handle setting the value, which passes the current answer as the first argument. It then uses that to properly set isRight and an observable correctAnswer that you could subscribe against.

这篇关于使用计算将KnockoutJS绑定到单选按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆