admin管理员组文章数量:1022405
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 bees correct.
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.
I put a putedObservable 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.
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.
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.
Full Fiddle
Full Source:
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 = koputed({
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>
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 bees correct.
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.
I put a putedObservable 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.
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.
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.
Full Fiddle
Full Source:
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.puted({
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>
Share
Improve this question
edited Apr 23, 2012 at 17:20
Adam Rackis
asked Apr 23, 2012 at 15:30
Adam RackisAdam Rackis
83.4k57 gold badges278 silver badges400 bronze badges
1 Answer
Reset to default 4Unless 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.
Here is a sample that uses a slightly different approach: http://jsfiddle/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.
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 bees correct.
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.
I put a putedObservable 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.
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.
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.
Full Fiddle
Full Source:
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 = koputed({
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>
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 bees correct.
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.
I put a putedObservable 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.
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.
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.
Full Fiddle
Full Source:
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.puted({
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>
Share
Improve this question
edited Apr 23, 2012 at 17:20
Adam Rackis
asked Apr 23, 2012 at 15:30
Adam RackisAdam Rackis
83.4k57 gold badges278 silver badges400 bronze badges
1 Answer
Reset to default 4Unless 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.
Here is a sample that uses a slightly different approach: http://jsfiddle/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.
本文标签: javascriptBinding KnockoutJS to Radio Button with computedStack Overflow
版权声明:本文标题:javascript - Binding KnockoutJS to Radio Button with computed - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745573977a2156905.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论