2012-12-10 60 views
2

我正在清理65 + html頁面和中央JavaScript庫的多頁面應用程序。我的html頁面有很多冗餘,中央js庫已經成爲意大利麪。我在合併頁面方面遇到了一些限制,因爲我在一個執行特定結構的較大框架內工作。我想減少冗餘並清理代碼。多頁面js應用程序的集中代碼

我發現了主幹,MVC模式,microtemplating和requirejs,但它們看起來最適合單頁應用。不知何故,我需要讓主模塊知道正在加載什麼頁面,以便將正確的元素放在頁面上。我正在考慮傳入html的標題,它將轉而獲取正確的頁面元素集合,並將它們作爲對象傳遞給App.initialize。

1)任何人都可以驗證這種方法嗎?如果沒有,建議採用其他方法嗎?如牽線木偶延伸到骨幹?

2)任何人都可以推薦一種方法來獲取頁面細節到骨幹框架?

以下骨幹教程我使用main.js構建了一個成功的測試頁面,該頁面調用調用view.render方法的App.initialize方法。我的第一個想法是讀取html頁面標題並使用它爲正在加載的特定頁面選擇一個模型。我不得不傳入一個具有每個頁面佈局細節的對象。這裏是視圖的渲染方法,所以你可以看到我想要做什麼:

  render: function() { // pass parameter to render function here? 
      var data = new InputModel, 
       pageTitle = data.pageTitle || data.defaults.pageTitle, 
       compiled, 
       template; 

      var pageElements = [ 
       { container: '#page_title_container', template: '#input_title_template' }, 
       { container: '#behavior_controls_container', template: '#behavior_controls_template' }, 
       { container: '#occurred_date_time_container', template: '#date_time_template' }] 

      for (var i = 0; i < pageElements.length; i++) { 
       this.el = pageElements[i].container; 
       compiled = _.template($(InputPageTemplates).filter(pageElements[i].template).html()); 
       template = compiled({ pageTitle: pageTitle }); 
       //pass in object with values for the template and plug in here? 
       $(this.el).html(template); 
      } 
     } 

您的幫助將不勝感激。更新我的大約1999年JavaScript技能,我有很多樂趣。語言有很多很酷的事情發生。

回答

1

使用文檔標題來選擇加載的腳本聽起來有點kludge-y。如果它有效,儘管如此。

另一個值得探索的想法可能是利用Backbone.RouterpushState:true來設置正確的頁面。當您在啓動時致電Backbone.history.start()時,路由器會擊中與當前網址匹配的路線,即您所在的頁面。

在路由回調中,您可以執行所有頁面特定的初始化。

您可以將模板和容器選擇從視圖中移到路由器中,並在initialize()函數(視圖的構造函數)中設置視圖。我說,是這樣的:

//view 
var PageView = Backbone.View.extend({ 
    initialize: function(options) { 
     this.model = options.model; 
     this.el = options.el; 
     this.title = options.title; 
     this.template = _.template($(options.containerSelector)); 
    }, 

    render: function() { 
     window.document.title = title; 
     var html = this.template(this.model.toJSON()); 
     this.$el.html(html); 
    } 
}); 

處理在路由器級視圖選擇:

//router 
var PageRouter = Backbone.Router.extend({ 
    routes: { 
     "some/url/:id": "somePage", 
     "other/url": "otherPage" 
    }, 

    _createView: function(model, title, container, template) { 
     var view = new PageView({ 
      model:model, 
      title:title 
      el:container, 
      templateSelector:template, 
     }); 
     view.render(); 
    }, 

    somePage: function(id) { 

     var model = new SomeModel({id:id}); 
     this._createView(model, "Some page", "#somecontainer", "#sometemplate"); 
    }, 

    otherPage: function() { 
     var model = new OtherModel(); 
     this._createView(model, "Other page", "#othercontainer", "#othertemplate"); 
    } 
}); 

而揭開序幕使用Backbone.history.start()

//start app 
$(function() { 
    var router = new PageRouter(); 
    Backbone.history.start({pushState:true}); 
} 

應用在這種類型的解決方案視圖代碼不需要了解其他視圖的特定代碼,並且如果您需要爲某些頁面創建更專業的視圖類,則不需要修改原始代碼。

一目瞭然,這似乎是一個乾淨的解決方案。當路由器想要開始捕捉路由時,當然可能會出現一些問題,並且您希望瀏覽器正常離開頁面。如果這導致嚴重的問題,或導致比基於標題的解決方案更大的混亂,原始解決方案可能仍然是可取的。

(代碼示例未經測試)

+0

感謝fencliff!我喜歡使用url(路由)來識別頁面的想法。這更符合骨幹(和要求)範式。我會試一試。 –

相關問題