1

一連の回答がある質問があります。各回答には、回答が正しいかどうかを表す isRight というブール値のプロパティがあります。

回答ごとにラジオボタンをレンダリングし、その回答が正しいかどうかをチェックしようとしています。ユーザーが別のボタンをクリックすると、その答えが正解になります。

KO はチェックされたプロパティを値にバインドし、ラジオの値がバインドされた値と一致する場合にのみ各ラジオ ボタンがチェックされることを理解しています。isRight に直接バインドすることはできません。

質問自体にcomputedObservableを配置しました。これですべてが実行されます。そして、それは機能します。問題は、ラジオ ボタンの変更イベントをサブスクライブして、いつ新しい回答が選択されたかを確認したい (そして ajax 要求を送信したい) ことです。私が抱えている問題は、変更ハンドラーで ko バインディングが更新されないことです。ハンドラーに遅延を設定すると、必要なものが得られるようですが、より直接的な解決策が望ましいです。

クリック イベントは完全に機能しているように見えますが、ラジオ ボタンが既にチェックされている場合でも、クリックされるたびに発生します。

change イベントでバインディングが確実に更新されるようにする方法はありますか? 現在のコードは ko 2.0 で、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:

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

1 に答える 1

4

「変更」イベントをサブスクライブする特定の理由がない限り、変更中のオブザーバブルへの手動サブスクリプションの使用を検討することをお勧めします。これにより、実際のデータが変更されるたびに通知を受けることができます。

少し異なるアプローチを使用するサンプルを次に示します: http://jsfiddle.net/rniemeyer/FvZXj/。関数を使用して値の設定を処理し、現在の回答を最初の引数として渡します。次に、それを使用して、サブスクライブisRightできるオブザーバブルを適切に設定します。correctAnswer

于 2012-04-23T18:09:53.757 に答える