问题
I have a requirement where the view gets updated with new data. Here is the code for the view:
<table>
<thead id="resultTableHeader">
<tr style="text-align: center" data-bind="foreach: columns">
<th style="text-align: center; height: 23px;" data-bind="visible: checked, text: header">
</th>
</tr>
</thead>
<tbody id="resultTableBody" data-bind="foreach: simpleSearchResultsArray">
<tr>
<td style="text-align: center; vertical-align: middle;">
<span data-bind="text: $index()+1"></span>
</td>
<td style="text-align: center; vertical-align: middle;">
<span data-bind="text: jobName"></span>
</td>
<td style="text-align: center; vertical-align: middle;">
<span data-bind="text:qName"></span>
</td>
</tr>
</tbody>
</table>
<button id="bindData1">bind data 1</button>
<button id="bindData2">bind data 2</button>
The view model for the same:
function SimpleSearchResults() {
var self = this;
self.index = ko.observable();
self.jobName = ko.observable();
self.qName = ko.observable();
};
function QuoteSimpleSearchVM() {
var self = this;
self.simpleSearchResultsArray = ko.observableArray([]);
self.gridOptions = {
columns: [{
header: 'Index',
dataMember: 'index',
checked: ko.observable(true)
}, {
header: 'Job Name',
dataMember: 'jobName',
checked: ko.observable(true)
}, {
header: 'Quote Name',
dataMember: 'qName',
checked: ko.observable(true)
}
]
};
self.Search = function (num) {
var temparray = [];
var bindData= [];
// data1 and data2 to consider as info from service
var data1= [{jobName: 'a', documentName: 'Quote1'},{jobName: 'b', documentName: 'Quote2'}];
var data2= [{jobName: 'c', documentName: 'Quote2'},{jobName: 'd', documentName: 'Quote4'}];
if(num=="1")
bindData= data1;
else
bindData= data2;
console.log(bindData);
for (var k = 0; k < bindData.length; k = k + 1) {
var temp = new SimpleSearchResults();
temp.index = k + 1;
temp.jobName = bindData[k].jobName;
temp.qName = bindData[k].documentName;
temparray.push(temp);
}
self.simpleSearchResultsArray = ko.observableArray([]);
self.simpleSearchResultsArray = ko.observable(temparray);
ko.applyBindings(QuoteSimpleSearchVMObj, document.getElementById("resultTableBody"));
}
};
var QuoteSimpleSearchVMObj;
$(document).ready(function () {
QuoteSimpleSearchVMObj = new QuoteSimpleSearchVM();
ko.applyBindings(QuoteSimpleSearchVMObj.gridOptions, document.getElementById("resultTableHeader"));
$("#bindData1").click(function(){
alert("1");
QuoteSimpleSearchVMObj.Search("1");
});
$("#bindData2").click(function(){
alert("2");
QuoteSimpleSearchVMObj.Search("2");
});
});
The method Search in view model is called many times, on click of each time, there is new data which is updated in the view model. The same has to updated in the view.
My problem is, the first time view model is bound to the view, the data appears correct. Suppose the first time the ul in the view has 3 li's - the data is bound correct.
The next time i click Search, there is new data in View model, suppose the ul has two li's the second time, the data is bound 6 times in the view. Each li appearing thrice since the first seach had created 3 li's. How to solve this issue?
Hope i am clear with the question. Let me know if any more details is needed.
The link for jsfiddle: http://jsfiddle.net/KRyXR/91/ The link doesn't replicate the situation. Trying to make my problem clear. Consider data1 to be the data bound during first search, and data2 to be the data bound on clicking second time.
Thanks in advance.
回答1:
With knockout you don't need rebind the view on each model modification. That's mean you don't need to call this on each search :
self.simpleSearchResultsArray = ko.observableArray([]);
self.simpleSearchResultsArray = ko.observable(temparray);
Just call the "setter" of the observable and the view will changed.
self.simpleSearchResultsArray(temparray);
I updated your fiddle in which I just bind only one times. I bound the whole viewmodel the whole table.
I hope it helps.
See fiddle
来源:https://stackoverflow.com/questions/17804656/how-to-bind-the-ul-elements-with-new-viewmodel-data-knockout-js