一周前我刚开始使用knockout.js,所以希望这很简单。我花了大约5个小时搜索谷歌和这个网站,我见过的所有建议似乎都没有用。我已经尝试将pagedPlayerList更改为justList,以删除代码中的那部分作为问题。
我有这个代码用knockout.js显示一些数据
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Attack</th>
<th>Defense</th>
<th>Level</th>
<th>IPH</th>
<th>Syndicate</th>
<th>Last Modified</th>
<th style="width: 100px; text-align:right;" />
</tr>
</thead>
<tbody data-bind=" template:{name:playerTemplateToUse, foreach: pagedPlayerList }"></tbody>
</table>
<ul class="pagination">
<li data-bind="css: { disabled: pageIndex() === 0 }"><a href="#" data-bind="click: previousPage">«</a></li>
</ul>
<ul class="pagination" data-bind="foreach: allPlayerPages">
<li data-bind="css: { active: $data.pageNumber === ($root.pageIndex() + 1) }"><a href="#" data-bind="text: $data.pageNumber, click: function() { $root.moveToPage($data.pageNumber-1); }"></a></li>
</ul>
<ul class="pagination">
<li data-bind="css: { disabled: pageIndex() === maxPlayerPageIndex() }"><a href="#" data-bind="click: nextPlayerPage">»</a></li>
</ul>
<script id="itemsPlayerTmpl" type="text/html">
<tr>
<td data-bind="text: id"></td>
<td data-bind="text: name"></td>
<td data-bind="text: att"></td>
<td data-bind="text: def"></td>
<td data-bind="text: lvl"></td>
<td data-bind="text: iph"></td>
<td data-bind="text: synd_name"></td>
<td data-bind="text: $root.lastModDate(last_modified)"></td>
<td class="buttons">
<a class="btn btn-sm btn-primary" data-bind="click: $root.edit" href="#" title="edit"><i class="glyphicon glyphicon-edit"></i></a>
<a class="btn btn-sm btn-primary" data-bind="click: $root.removePlayer" href="#" title="remove"><i class="glyphicon glyphicon-remove"></i></a>
</td>
</tr>
</script>
<script id="editPlayerTmpl" type="text/html">
<tr>
<td data-bind="text: id"></td>
<td><input data-bind="value: name"/></td>
<td><input size="8" data-bind="value: att"/></td>
<td><input size="8" data-bind="value: def"/></td>
<td><input size="3" data-bind="value: lvl"/></td>
<td><input size="8" data-bind="value: iph"/></td>
<td>
<select data-bind="options: $root.syndList, optionsText: 'name', optionsValue: 'id', value: synd_id, selectedOptions: 'synd_id', optionsCaption: 'Please select...'"></select>
</td>
<td data-bind="text: $root.lastModDate(last_modified)"></td>
<td class="buttons">
<a class="btn btn-sm btn-success" data-bind="click: $root.savePlayer" href="#" title="save"><i class="glyphicon glyphicon-ok"></i></a>
<a class="btn btn-sm btn-primary" data-bind="click: $root.cancel" href="#" title="cancel"><i class="glyphicon glyphicon-trash"></i></a>
</td>
</tr>
</script>
加载页面时效果很好。问题是,我希望每2分钟自动更新一次数据,当我在显示器中加载数据时不会更新。
以下是javascript的相关部分
self.playerList = ko.observableArray();
<?php if(isset($playerlist)) { ?>
self.playerList(jQuery.parseJSON('<?php echo addslashes($playerlist); ?>'));
<?php } ?>
self.lastModDate = function(data){
var myDate = new Date(data * 1000);
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var month = months[myDate.getMonth()];
var date = myDate.getDate();
var year = myDate.getFullYear();
var time = date+', '+month+' '+year;
return time;
}
// ALL PLAYERS TAB
self.addPlayer = function () {
var newItem = new Player();
self.playerList.push(newItem);
self.selectedItem(newItem);
self.moveToPage(self.maxPlayerPageIndex());
};
self.removePlayer = function (item) {
if (item.id) {
if (confirm('Are you sure you wish to delete this item?')) {
$.post('<?php echo base_url('front/deleteplayer'); ?>', item).complete(function (result) {
if(result = '1'){
toastr.success("The player has been removed.", "");
self.playerList.remove(item);
if (self.pageIndex() > self.maxPlayerPageIndex()) {
self.moveToPage(self.maxPlayerPageIndex());
}
} else {
toastr.error("There was a problem removing the player", "");
}
});
}
}
else {
self.list.remove(item);
if (self.pageIndex() > self.maxPlayerPageIndex()) {
self.moveToPage(self.maxPlayerPageIndex());
}
}
};
self.savePlayer = function () {
var item = self.selectedItem();
$.post('<?php echo base_url('front/saveplayer'); ?>', item, function (result) {
console.log(item);
toastr.success("Your changes have been saved.", "");
self.selectedItem(null);
});
};
self.pagedPlayerList = ko.dependentObservable(function () {
var size = self.pageSize();
var start = self.pageIndex() * size;
return self.playerList().slice(start, start + size);
});
self.maxPlayerPageIndex = ko.dependentObservable(function (list) {
return Math.ceil(self.playerList().length / self.pageSize()) - 1;
});
self.nextPlayerPage = function () {
if (self.pageIndex() < self.maxPlayerPageIndex()) {
self.pageIndex(self.pageIndex() + 1);
}
};
self.allPlayerPages = ko.dependentObservable(function () {
var pages = [];
for (i = 0; i <= self.maxPlayerPageIndex() ; i++) {
pages.push({ pageNumber: (i + 1) });
}
return pages;
});
self.playerTemplateToUse = function (item) {
return self.selectedItem() === item ? 'editPlayerTmpl' : 'itemsPlayerTmpl';
};
// END ALL PLAYERS TAB
self.edit = function (item) {
self.selectedItem(item);
self.currentSynd(item.synd_id);
};
self.cancel = function () {
self.selectedItem(null);
};
self.previousPage = function () {
if (self.pageIndex() > 0) {
self.pageIndex(self.pageIndex() - 1);
}
};
self.moveToPage = function (index) {
self.pageIndex(index);
};
然后这是绑定/更新代码
// SELF UPDATING DATA
update = function() {
siteModel.updatePlayerList();
console.log(siteModel.playerList);
}
var siteModel = new siteModel();
window.setInterval(update,60000);
ko.applyBindings(siteModel);
这是updatePlayerList函数
self.updatePlayerList = function(){
$.ajax({
url:'<?php echo base_url('front/listplayers'); ?>',
success:function(data) {
var obj = jQuery.parseJSON(data);
self.playerList = (obj);
}
});
}
updatePlayerList第一次触发这是服务器返回内容的摘录:
[{"id":"19","name":"AlDavisJR","att":"818741","def":"895287","lvl":"227","iph":"2804866","synd_id":"9","last_modified":"1384284327","synd_name":"FIGHT CLUB"},{"id":"15","name":"aLEX","att":"95748","def":"112386","lvl":"227","iph":"16033","synd_id":"15","last_modified":"1384240593","synd_name":"iron"}]
但是console.log(self.playerList);显示空白值。运行console.log的第二次以及随后的任何时间都会显示正确的数据。
问题是表始终显示首次加载页面时加载的数据。如果我修改数据库,则ajax调用会返回新数据,但不会上传该站点。
答案 0 :(得分:0)
有很多代码,所以可能会有更多的代码,但我发现的第一件事是你在self.updatePlayerList函数中更新了错误的数据。
var obj = jQuery.parseJSON(data);
self.playerList = (obj); // This assigns obj to self.playerList, overwriting the observableArray
取而代之的是
self.playerList(obj); // This keeps the observable intact, and assigns obj as it's new internal value
如果能解决这个问题,请告诉我!
修改强>
另外,你的console.log第一次出现空白的原因是因为updatePlayerList是一个异步函数(因为你的ajax调用是异步执行的)。因此,将调用ajax函数,并且在检索数据时,您已将observableArray的值输出到控制台。相反,您将要等到成功回调触发,然后在那里登录到控制台以检查值是否正确。
另一个可能有用的提示:当您将observable记录到控制台时,您将无法查看observable的实际值。辅助函数ko.toJS(yourObservableHere)
和ko.toJSON(yourObservableHere)
对于检索(嵌套)可观察对象的实际值非常有用。第一个用你输入的任何东西制作一个简单的javascript对象(删除可观察的包装器),第二个做同样的事情,但是将它全部输出到一个JSON字符串。这对于在UI中进行调试非常有用(例如<div data-bind="text: ko.toJSON(yourViewModel)"></div>