2012-03-04 104 views
7

我使用jQuery $.ajax調用和Knockout JS生成的頁面上有附件列表。ajax調用Knockout JS後刷新列表

我的HTML看起來像(這是剝開):

<tbody data-bind="foreach: attachments"> 
    <tr> 
    <td data-bind="text: Filename" /> 
    </tr> 
</tbody> 

我有得到它返回一個JSON響應附件列表功能:

$(function() { 
    getFormAttachments(); 
}); 

function getAttachments() { 
    var request = $.ajax({ 
    type: "GET", 
    datatype: "json", 
    url: "/Attachment/GetAttachments" 
    }); 

    request.done(function (response) { 
    ko.applyBindings(new vm(response)); 
    }); 
} 

我的視圖模型看起來像:

function vm(response) { 
    this.attachments = ko.observableArray(response); 
}; 

有一個刷新按鈕,用戶可以點擊刷新此列表,因爲在可能已添加時間附件/刪除:

$(function() { 
    $("#refresh").on("click", getAttachments); 
}); 

附件列表的初始渲染是好的,但是當我通過刷新按鈕再次調用getAttachments單擊列表加入到(其實每個產品重複數次)。

我創建了一個的jsfiddle在這裏演示此問題:

http://jsfiddle.net/CpdbJ/137

我在做什麼錯?

+0

Kev - 不錯的帖子。我仍然有點困惑。新淘汰賽。我在加載頁面時僅僅通過AJAX數據加載ViewModel時遇到了類似的麻煩。我相信我錯過了一個微小而嚴肅的觀點。讓我困惑的一件事是一些教程將'viewmodel'作爲一個對象(例如'var viewmodel = {something:ko.observable()}')和其他函數(函數ViewModel(){this.something = ko。observable()}') - 任何建議? – 2012-03-16 00:43:09

+0

@ one.beat.consumer - 查看我的後續問題:http://stackoverflow.com/questions/9589419/difference-between-knockout-view-models-declared-as-object-literals-vs-functions - the回答和下面的評論應該讓事情更清楚。我建議花25美元,並觀看這個:http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=knockout-mvvm – Kev 2012-03-16 02:30:18

+0

我會檢查你的其他問題;謝謝。我有一個複合視覺訂閱,我已經看了2-3次...他們幾乎沒有刮過表面,現在大部分都是舊的,現在2.0已經出來,他們正在使用1.2或1.3測試版... – 2012-03-16 05:48:14

回答

10

這是一個修復你的示例的小提琴。你最大的問題是你多次調用'applyBindings'。一般來說,您將在頁面加載時調用applyBindings,然後頁面將與View Model交互,以使Knockout刷新頁面的某些部分。

http://jsfiddle.net/CpdbJ/136

HTML

<table> 
    <thead> 
     <tr><th>File Name</th></tr> 
    </thead> 
    <tbody data-bind="foreach: attachments"> 
     <tr><td data-bind="text: Filename" /></tr> 
    </tbody> 
</table> 
<button data-bind="click: refresh">Refresh</button> 

的JavaScript

$(function() { 
    var ViewModel = function() { 
    var self = this; 

    self.count = 0; 
    self.getAttachments = function() { 
     var data = [{ Filename: "f"+(self.count*2+1)+".doc" }, 
        { Filename: "f"+(self.count*2+2)+".doc"}]; 
     self.count = self.count + 1; 
     return data; 
    } 

    self.attachments = ko.observableArray(self.getAttachments()); 

    self.refresh = function() { 
     self.attachments(self.getAttachments());   
    } 
    }; 

    ko.applyBindings(new ViewModel()); 
}); 

-

您可能也想看看映射插件 - http://knockoutjs.com/documentation/plugins-mapping.html。它可以幫助您將JSON轉換爲視圖模型。此外,它可以指定一個屬性作爲對象的「關鍵字」......這將用於確定後續映射中的舊對象和新對象。

這裏是一個小提琴我寫了一段時間後表現出類似的想法:

http://jsfiddle.net/wgZ59/276

注:我用「更新」爲我的映射規則的一部分,但只有這樣我就可以登錄到安慰。如果您想自定義映射插件更新對象的方式,則只需添加此項即可。

+0

這將如何工作if說我沒有數據,我需要調用一個Ajax方法和一個GET? – Vyache 2014-02-03 16:07:28

+0

只需更改getAttachments調用以進行AJAX調用,並在回調中將結果直接設置到附件observable數組中。刷新只會調用self.getAttachments()。附件將被初始化爲空,然後您可以立即調用self.getAttachments()進行第一次AJAX調用。一旦回調設置結果Knockout將負責刷新您的用戶界面。 – 2014-02-04 13:12:30

+0

嗯,出於某種原因,我不能刷新我的數據與此方法,請參閱我的問題:http://stackoverflow.com/questions/21558075/how-do-i-update-my-model-using-ajax-and -mapping-插件 – Vyache 2014-02-04 16:39:08