问题
My page is as follows:
<button id="add">Add Data</button>
<button id="show">show</button>
<table>
<tr style="vertical-align:top">
<td>
<table border="1">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody data-bind="foreach: students">
<tr>
<td data-bind="text: id"></td>
<td>
<input type="text" data-bind="value: name" />
</td>
<td> <a href="javascript:void(0)" data-bind="click: $root.showData">Select</a>
</td>
</tr>
</tbody>
</table>
</td>
<td>
<table id="data">
<tbody data-bind="with: selectedData">
<tr>
<td>Id</td>
<td>
<input type="text" data-bind="value: id" />
</td>
</tr>
<tr>
<td>Name</td>
<td>
<input type="text" data-bind="value: name" />
</td>
</tr>
<tr>
<td></td>
<td>
<input type="button" value="Close" />
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
The javascript is as follows:
function ViewModel() {
var self = this;
self.students = ko.observableArray([]);
self.showData = function (dt) {
if (window.console) console.log(dt);
self.selectedData(dt);
$('#data').show();
}
this.selectedData = ko.observable();
}
$(function () {
window.appViewModel = new ViewModel();
ko.applyBindings(window.appViewModel);
$('#add').click(function () {
var model = window.appViewModel;
$.each(students, function (idx, student) {
if (window.console) console.log(student);
model.students.push(student);
});
$('table').show();
});
$('table').hide();
$('input').click(function () {
$('#data').hide();
});
$('#show').click(function () {
var s = JSON.stringify(window.appViewModel.students());
alert(s);
});
});
Preview:
In pic, I click on the select corresponding to student with id = 3. The other table shows up with the selected student details. Suppose I enter something in textbox 1, textbox 2 doesn't update, and vice versa.
What to do to make that happen?
Fiddle: http://jsfiddle.net/deostroll/YdrQf/1/
回答1:
Your inputs aren't updating because the id
and name
values are not being stored or bound against observables
, which are the special object that knockout provides specifically for this purpose. You can easily solve this with your code by adding a new Student
type:
function Student(data) {
this.id = ko.observable(data.id);
this.name = ko.observable(data.name);
};
and use it to populate your students
array with:
$.each(students, function (idx, student) {
if (window.console) console.log(student);
model.students.push(new Student(student));
});
With those properties now being observables
, their changes will propagate to the UI. Here is the fiddle, with these two minor changes.
That being said, I think you have largely missed the point of Knockout. I strongly suggest you go through the Knockout tutorials, if you haven't done so already.
You're use of jQuery to create click
functions for your viewmodel really goes against the model that Knockout encourages. Please take a look at this fiddle, which converts your code into 100% Knockout, using viewmodel functions, and drops all the jQuery.
来源:https://stackoverflow.com/questions/17868717/two-way-binding-of-a-single-object-in-observablearray