我很难让一个简单的单页应用程序工作。检查浏览器中的各种调试工具后,我可以看到它正确触发搜索并以正确的格式返回JSON。但是,foreach
绑定似乎没有触发,并且表永远不会填充。
相关的HMTL:
<!-- Folders -->
<ul class="folders" data-bind="foreach: folders">
<li data-bind="text: $data,
css: { selected: $data == $root.chosenFolderId() },
click: $root.goToFolder"></li>
</ul>
<!-- Tickets grid -->
<table class="tickets" data-bind="with: chosenFolderData">
<thead><tr><th>ID</th><th>Description</th><th>Status</th></tr></thead>
<tbody>
<!-- ko foreach: tickets -->
<tr data-bind="click: $root.goToTickets">
<td data-bind="text: id()"></td>
<td data-bind="text: message()"></td>
<td data-bind="text: is_active()"></td>
</tr>
<!-- /ko -->
</tbody>
</table>
脚本:
function WebticketViewModel() {
// Data
var self = this;
self.folders = ['All', 'Open', 'Closed'];
self.chosenFolderId = ko.observable();
self.chosenFolderData = ko.observable();
self.chosenTicketData = ko.observable();
// Behaviours
self.goToFolder = function(folder) {
self.chosenFolderId(folder); // Mark folder as selected
self.chosenTicketData(null); // Stop showing a ticket
$.get('search.php', { folder: folder }, self.chosenFolderData); // Fetch folder data and update view
};
self.goToTickets = function(ticket) {
self.chosenFolderId(ticket.folder); // Mark ticket as selected
self.chosenFolderData(null); // Stop showing a folder
$.get('search.php', { ticketID: ticket.id }, self.chosenTicketData); // Fetch ticket data and update view
};
// Show inbox by default
self.goToFolder('All');
};
ko.applyBindings(new WebticketViewModel());
答案 0 :(得分:0)
您可以使用observable函数作为ajax调用的success
回调函数。不要这样做。相反,有一个适当的函数来处理结果。您已经在您的视图中期望得多,因为tickets
似乎具有可观察的属性。
为故障单创建一个构造函数,如下所示:
function Ticket(data) {
this.id = ko.observable(data.id);
this.message = ko.observable(data.message);
this.is_active = ko.observable(data.is_active);
}
按照这些方式处理ajax调用:
$.get('search.php', { folder: folder }, function(data) {
self.chosenFolderData({
tickets: data.map(function(d) { return new Ticket(d); })
});
});
这是一个完整的演示:
// Fake data:
$ = {
get: function(url, data, callback) {
if (data.folder && data.folder === "All") { callback([{id:1, message:"My Message AAAA", is_active:true}]); }
else if (data.folder && data.folder === "Open") { callback([{id:1, message:"My Message BBBB", is_active:false}, {id:1, message:"My Message CCCC", is_active:true}]); }
else callback([]);
}
};
function Ticket(data) {
this.id = ko.observable(data.id);
this.message = ko.observable(data.message);
this.is_active = ko.observable(data.is_active);
}
function WebticketViewModel() {
// Data
var self = this;
self.folders = ['All', 'Open', 'Closed'];
self.chosenFolderId = ko.observable();
self.chosenFolderData = ko.observable();
self.chosenTicketData = ko.observable();
// Behaviours
self.goToFolder = function(folder) {
self.chosenFolderId(folder); // Mark folder as selected
self.chosenTicketData(null); // Stop showing a ticket
$.get('search.php', { folder: folder }, function(data) {
self.chosenFolderData({
tickets: data.map(function(d) { return new Ticket(d); })
});
}); // Fetch folder data and update view
};
self.goToTickets = function(ticket) {
self.chosenFolderId(ticket.folder); // Mark ticket as selected
self.chosenFolderData(null); // Stop showing a folder
$.get('search.php', { ticketID: ticket.id }, self.chosenTicketData); // Fetch ticket data and update view
};
// Show inbox by default
self.goToFolder('All');
};
ko.applyBindings(new WebticketViewModel());
&#13;
li:hover { cursor: pointer; color: red; }
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<!-- Folders -->
<ul class="folders" data-bind="foreach: folders">
<li data-bind="text: $data,
css: { selected: $data == $root.chosenFolderId() },
click: $root.goToFolder"></li>
</ul>
<!-- Tickets grid -->
<table class="tickets" data-bind="with: chosenFolderData">
<thead><tr><th>ID</th><th>Description</th><th>Status</th></tr></thead>
<tbody>
<!-- ko foreach: tickets -->
<tr data-bind="click: $root.goToTickets">
<td data-bind="text: id()"></td>
<td data-bind="text: message()"></td>
<td data-bind="text: is_active()"></td>
</tr>
<!-- /ko -->
</tbody>
</table>
&#13;