2013-02-18 32 views
6

我有一個相當複雜的網頁,包含各種選項卡,窗體,單選按鈕,下拉菜單等。它們都使用Knockout.js綁定到通過AJAX調用加載的非常複雜的JavaScript對象。當然,用戶可以隨心所欲地操作,在這一點上,他們點擊一個按鈕,將所有更改保存到服務器。是否有使用Knockout綁定頁面進行跟蹤的標準方式?

我正在設計一個好的設計,以跟蹤頁面上發生了什麼變化,以便我可以實施保存。所以,我想出了一些可能的實現。

選項1)把所有東西都發回去,讓服務器把它整理出來:用這個方法,我讓Knockout只是更新數據源。 保存按鈕會調用.toJS()並將該數據發送回服務器。 優點:這很容易,而且在客戶端上只需很少的工作。 缺點:服務器並不知道發生了什麼變化,必須從數據庫加載數據進行比較,或者只保存所有字段。這些字段來自多個表並且具有複雜的關係。它也將整個文檔視爲一個單一的原子單位。如果其他人更改了字段A並且您更改了字段B,則一個用戶將失去其更改。

選項2)使用JavaScript來比較原始數據和當前數據:使用這種技術,當在保存用戶點擊按鈕,我想系統地比較原始數據和當前數據並生成圖表的變化。 優點:這將理想的結果是一個精確的用戶改變的圖形,如果沒有改變,甚至可以不操作。 缺點:我綁定的數據很複雜。它由字符串,數組,對象,對象數組,對象數組與其他對象等組成。尋找更改將是一個相當複雜的嵌套循環。

選項3)在UI中進行跟蹤更改:我必須在發生更改時觀察更改,並在更改UI元素時保持增量。 保存按鈕只會將該更改圖發送到服務器,如果它有任何掛起的更改。 優點:沒有必要比較兩個巨大的JavaScript對象尋求變化,但仍然有選項2. 缺點的所有優點:淘汰賽不出現有一個標準的方式使用單一聽取所有的變化事件處理器。我相信我不得不訴諸綁定到所有的UI元素,或者在Knockout中創建自定義的bindingHandlers來實現這個實時更改跟蹤。

我的問題:

我的問題主要是爲Knockout.js專家。有沒有標準的方法,或建議指導方針來解決這種明顯的常見情況?發回所有的數據,甚至是沒有改變的東西,一個共同的設計?或者是否有人實施自定義更改跟蹤器? Knockout是否提供了任何可以減輕這種需求的框架?

更新:找到this thing,不知道它是否有用,或者如果有人對此有任何反饋。

+2

剛剛經歷了一件非常相似的事情,我傾向於選擇1.我們走向選擇3,它以心痛結束。另一件事你必須考慮如果用戶取消他們的操作(如果你允許)?你必須有一些機制來回滾更改。使用選項1,您可以向服務器請求舊數據(或者做一些更具創造性的事情,因爲這看起來過多),或者您可以使用[受保護的觀察值](http://www.knockmeout.net/2011/03/guard - 您的模型 - 接受 - 或 - 取消 - edits.html)。 – 2013-02-18 23:40:59

回答

1

如果它的啓用/禁用保存按鈕,允許用戶「來自」該網頁/導航狀態的問題,那麼你就可以用https://github.com/CodeSeven/kolite

檢查檢查knockout.dirtyFlag.js

希望這有助於。

編輯:請記住,您應該「永不」信任來自「用戶界面」的數據。真正的比較和驗證,最終會進入服務器內的「受控」環境。

1

我可能會做的是採取選擇2 - 比較本身可以很簡單,比如將JS對象串化並將其與其緩存版本進行比較。

討論了其他幾個選項here

P.S.也許ko.mapping可以幫助你管理這個JS對象的怪物?

1

我寫了淘汰賽的變化跟蹤器擴展,皮特·史密斯大大擴展...

到這裏看看: https://roysvork.wordpress.com/2014/01/12/tracking-changes-to-complex-viewmodels-with-knockout-js/

它適用於延長觀察到的原則,以跟蹤初始狀態VS 。改變用戶在客戶端做出的改變。我認爲這個功能非常棒,並且可以向用戶提供實時反饋,以瞭解他們修改了哪些內容。在實踐中,我們實際上實現了一個保存面板,顯示所有待處理的更改,甚至可以通過使用更改跟蹤器的可重用功能來撤消單個更改。

ko.extenders.trackChange = function (target, track) { 
    if (track) { 
     target.isDirty = ko.observable(false); 
     target.originalValue = target(); 
     target.subscribe(function (newValue) { 
      // use != not !== so numbers will equate naturally 
      target.isDirty(newValue != target.originalValue); 
     }); 
    } 
    return target; 
}; 
相關問題