2015-12-13 153 views
0

我正在努力獲得一個簡單的單頁應用程序工作。在瀏覽器中檢查各種調試工具後,我可以看到它正確地觸發搜索並以正確的格式返回JSON。但是,foreach綁定似乎沒有觸發,並且該表永遠不會填充。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

您使用可觀察到的功能作爲success回調Ajax調用。不要這樣做。相反,有一個適當的函數來處理結果。您已經期望儘可能多的,因爲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());
li:hover { cursor: pointer; color: red; }
<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>

+0

感謝您的建議。我已經實施了您所做的更改,以及假數據和頁面功能。我仍然不確定如何刪除僞造的數據,並讓它引用我真正的JSON。 –

+0

解決了最後一步。這是不正確的猜測,回調是JSON,所以必須在.get函數中明確說明。 –