2

我剛剛開始使用KnockoutJS,並將它與PagerJS,SammyJS和BootStrap結合使用來構建單頁應用程序,並且我有點迷路馬上。如何使用KnockoutJS,SammyJS和pagerJS組織一個SPA

令我吃驚的是我該如何組織視圖模型,並以簡單且可重用的方式組合路由和頁面?現在感覺就像一大堆鬆散的東西,幾乎不適合。我已經檢查了一些關於這個問題的答案,但是我仍然沒有弄清楚如何組織應用程序。

目前我在頁面上有一個viewmodel,作爲概念的證明,它只是處理用戶的個人信息和即將發生的事件的顯示。然而,現在我必須包含其他類型的信息,並且有一個視圖模型,而不是多個視圖模型似乎不正確,因爲用戶需要能夠管理他/她的事件,聯繫人和任務並列出其他用戶,事件和任務等等。還有更多是要來的。

幾乎所有用戶選擇/選擇的選項都在數據庫中定義。例如,數據庫中預定義了用戶任務和解決這些任務的相應操作。

大多數示例傾向於將SammyJS路由放入viewmodel中,但是當在頁面上有多個viewmodel時,我想將SammyJS從單個viewmodel移到它自己的位置,即只有一個位置來編輯路徑。

我的想法是使用PagerJS容易不同視圖之間進行切換,但它需要在SammyJS設置路徑和用於PagerJS數據綁定路徑之間的同步。例如,當選擇#!/ user時,Sammy中的路由處理請求並獲取要顯示的數據,PagerJS顯示用戶頁面。對我來說感覺有點脆弱,但這也許是它應該如何運作的。

+0

你也可以看看[擊退(http://kmalakoff.github.com/knockback/);一個採用Knockout和Backbone的「兩全其美」的框架(包括路由和歷史支持)。 – MarcoK 2013-02-22 10:46:42

回答

2

事先一些注意事項:

我使用RequireJS分我的應用程序成模塊 - 這是不是必需的(沒有雙關語意) - 你可以先把東西都堆在一個JavaScript文件就了事,我覺得組織起來更容易。 This question顯示了我的項目佈局。

我也沒有使用SammyJS進行路由,但是使用了Crossroads和Hasher。這些概念應該有點相同。

下面的例子可能不是你所做的100%匹配,但希望它給你一個我正在使用的方法的想法。

我的main.js包含所有的路由信息​​,並且在每個路由處理程序中,我使用RequireJS中的require()來拉入我用於該路由的模塊。每個模塊包含了淘汰賽視圖模型和幾種方法來做事像視圖模型加載數據,在某些情況下將其綁定等

main.js這裏是我如何處理路線顯示#/person/id路線:

crossroads.addRoute("person/{id}", function(id){ 
    require(["person"], function(person) { 
     var model = person.load(id); 
     person.view($('#content'), model); 
    }); 
}); 

person.js重要的部分:

define(['jquery', 'knockout', ...], function($, ko, ...) { 
    var person = {}; 
    person.Model = function Model(id) { 
     this.id = ko.observable(id); 
     this.name = ko.observable(); 
     // more properties and methods removed... 
    }; 

    person.load = function(id) { 
     var model = new person.Model(id); 
     var request = $.ajax({ 
      // ajax config properties removed... 
      'success' : function(resp) { 
       model.name (resp.name); 
       // more property setting removed... 
      } 
     }); 
     return model; 
    }; 

    person.view = function(element, model) { 
     // Using require text plugin to load templates... 
     require(['text!templates/person/view.tmpl.html'], function(ViewTemplate) { 
      element.empty(); 
      element.html(ViewTemplate).ready(function() { 
       ko.applyBindings(model, element.get(0)); 
       // any further setup needed below... 
      }); 
     }); 
    }; 
    return person; 
}); 
+0

感謝您的回覆。你的方法一定很有趣。你不使用像pagerjs這樣的輔助函數庫在視圖之間切換 - 我假設你使用每個視圖的模板來代替?我正在考慮擺脫pagerjs,因爲它弄亂了我對我應該如何繼續的看法。 – 2013-02-25 15:58:47