2

我目前正在編寫一個Backbone Marionette應用程序,最終總計大約6個不同的「屏幕」或頁面,這些應用程序會經常共享內容,我不確定如何最佳結構和訪問區域。Backbone Marionette使用Require.js,Regions和如何設置

我正在使用此處描述的應用/模塊設置:StackOverflow question 11070408: How to define/use several routings using backbone and require.js。這將是一個應用程序,它將隨着時間的推移添加新功能和內容,並且需要可擴展(並且顯然儘可能重複使用)

我正在構建的單頁應用程序在每個應用程序上有4個主要部分屏幕:標題,主要內容,輔助內容,頁腳。

頁腳在所有頁面上將保持一致,頁眉在3頁上相同,並在其餘3頁上略有修改(使用約80%的相同元素/內容)。 「更多內容」區域將在各個頁面上重複使用。

在我app.js文件,我確定我區像這樣:

define(['views/LandingScreen', 'views/Header', 'router'], function(LandingScreen, Header, Router) { 
    "use strict"; 
    var App = new Backbone.Marionette.Application(); 

    App.addRegions({ 
     header: '#mainHeader', 
     maincontent: '#mainContent', 
     morecontent: '#moreContent', 
     footer: '#mainFooter' 
    }); 

    App.addInitializer(function (options) { 

    }); 

    App.on("initialize:after", function() { 
     if (!Backbone.History.started) Backbone.history.start(); 
    }); 

    return App; 
}); 

現在,在上述後回頭參考應用程序的設置,這將是處理該地區的最佳方式。我是否會獨立重申每個子應用程序中的每個區域?這似乎是保持模塊儘可能獨立的最佳方式。如果我走這條路線,在子應用程序之間打開/關閉或隱藏/顯示這些區域的最佳方式是什麼?

或者,我是否在app.js中聲明區域?如果是這樣,那麼我將如何從子應用程序最好地改變和編排這些區域的事件?在app.js文件中定義區域似乎與保持模塊和核心應用相互瞭解的最小限度相反。另外,我看到的每個示例都有主應用程序文件中的appRegions方法。那麼從子應用程序訪問和更改這些區域的最佳做法是什麼?

在此先感謝!

+0

對不起,我一直在根據我得到的兩個答案辯論AMD與非AMD。對於長期計劃,儘管事實上我覺得我花更多的時間去搞清楚管理依賴關係的問題,而不是我的應用程序的功能,但最好還是選擇AMD的路線。 – mindpivot

回答

4

我實際上有一個根應用程序,負責啓動子應用程序,並通過它應顯示的區域。我還使用基於Backbone.SubRoute的自定義組件,該子組件支持子應用程序的相對路由。

檢查出這個要點:https://gist.github.com/4185418

你可以很容易地適應它發送一個「配置」對象定義多個區域addRegions,而不是region值我發送到子應用程序start方法

請記住,只要您在Marionette中致電someRegion.show(view),它將首先關閉當前顯示的視圖。如果您有兩個不同的區域,每個區域都在自己的應用程序中定義,但兩者都綁定到相同的DOM元素,唯一重要的是最近調用哪個區域的show。然而,這很麻煩,因爲你沒有得到關閉前一個視圖的優點 - 例如解綁定事件綁定器。這就是爲什麼,如果我有一個子應用程序從某種根應用程序「繼承」一個區域,我通常只是將實際的區域實例從該根應用程序傳遞到子應用程序,並保存一個引用作爲子應用程序的一個屬性。這樣我仍然可以撥打subApp.regionName.show(view),它可以完美運行 - 如果您想要將事件從您所在的區域上傳到您的應用程序(因爲該區域屬於根應用程序,所以可能會搞砸的唯一事情就是您的事件鏈)比子應用程序)。通過幾乎總是使用單獨的Marionette.EventAggregator實例來管理事件,而不是依賴區域/視圖/控制器/等的內置功能,我解決了這個問題。

這就是說,你可以得到兩全其美的最好的 - 你可以通過區域實例到你的子應用程序,保存對它的引用,這樣你就可以調用「close」,然後使用它的regionInstance.el屬性來定義你的自己的區域實例指向相同的元素。

for(var reg in regions) if regions.hasOwnProperty(reg) { 
    var regionManager = Marionette.Region.buildRegion(regions[reg].el, 
      Marionette.Region); 
    thisApp[reg] = regionManager; 
} 

這一切都取決於你的重點是什麼。

+0

同步,好的答案。關於你的要點,我有幾個問題。 1)Application.root.js的第43行:抽象是什麼樣的? 2)第73行相同,初始化中有什麼:ui方法?這足以脫離我如何處理那些讓我失望的事情。 3)在main.js中,我假設從第18行開始的數組是我將其他subApp添加到整個應用程序的地方? 4)vent.super.js:你說第7行應該只被root app使用。所有其他應用程序應該使用'EchoVent'。什麼是EchoVent?它有什麼特別的或者是標準的EventAggregator? – mindpivot

+0

第一個快速回答: 3)是 4)'EchoVent'是我的一個超級用語,它用一個名稱空間和至少一個現有通風口實例作爲參數實例化。它的初始值設定項綁定到特殊的「all」事件,並簡單地在任何通過echovent註冊的通道上「回聲」出來,並提供名稱空間作爲事件名稱的前綴。例如,如果我已經完成了var ev = new EchoVent(「appName」,rootVent)',然後在echoVent上觸發了「app:started」,它會觸發該事件,但也會觸發'appName:app:started'在rootVent上。 – Isochronous

+0

1)我剛剛爲這個問題的答案創建了另一個要點,因爲這裏的評論部分有點長。這是鏈接:https://gist.github.com/4439430。哦,我忘了提及我將原始代碼添加到原始的要點中,所以如果你想看到它,請閱讀原始答案中的要點。雖然這很醜陋,但是請不要評價我; P – Isochronous

2

我個人更喜歡在我的Marionette應用程序中使用模塊。我覺得它消除了require.js爲您的應用程序添加的複雜性。在我目前正在開發的應用程序中,我創建了一個定義我的骨幹應用程序的app.js文件,但我使用了一個控制器模塊來加載我的路線,填充我的集合並填充我的區域。

app.js - >

var app = new Backbone.Marionette.Application(); 
app.addRegions({ 
    region1: "#region1", 
    region2: "#region2", 
    region3: "#region3", 
    region4: "#region4" 
}); 

app.mainapp.js - >

app.module('MainApp', function(MainApp, App, Backbone, Marionette, $, _) { 
    // AppObjects is an object that holds a collection for each region, 
    // this makes it accessible to other parts of the application 
    // by calling app.MainApp.AppObjects.CollectionName.... 
    MainApp.AppObjects = new App.AppObjects.Core(); 

    MainApp.Controller = new Backbone.Marionette.Controller.extend({ 
    start: function() { 
     // place some code here you want to run when the controller starts 
    } //, you can place other methods inside your controller 
    }); 

    // This code is ran by Marionette when the modules are loaded 
    MainApp.addInitializer(function() { 
    var controller = new MainApp.Controller(); 
    controller.start(); 
    }); 
}); 

然後,您可以把將要在控制器訪問另一個模塊內部的路線。

然後在網頁中,您可以通過調用來啓動一切。

$(function() { 
    app.start(); 
}); 

木偶將自動運行並加載所有模塊。

我希望這能讓你在某個方向開始。對不起,我無法複製並越過整個應用程序代碼來給你更好的例子。一旦這個項目完成,我將重新創建一個演示應用程序,我可以推送到網絡。

+0

Kalpers,感謝您的輸入。我絕對很想去模塊化路線,但我最終並不覺得它會給我靈活性,我需要在路上確保我的應用程序的模塊化。我爲大型協會工作,並需要創建儘可能可重用的模塊。我知道理論上模塊應該被寫成可重用,但實際上它太容易了。 AMD將會像有時那樣痛苦,這是我有點吝嗇的選擇。模塊路線現在會幫助我,但長期傷害我。非常感謝你的深思熟慮的迴應 – mindpivot

相關問題