2016-01-11 28 views
0

我正在構建一個非常簡單的Marionette應用程序;我不使用Marionette.Module,因爲它已被棄用,並且因爲我想使用帶有Webpack的ES2015。MarionetteJS:誰負責顯示子應用程序?

我只有幾個「頁面」:一個是歡迎屏幕,另一個是遊樂場。這些頁面中的每一個都是Applications,另外還有一個帶有Layout的根應用程序,只有三個區域:頁眉,主頁和頁腳。

這些應用程序的視圖(或佈局)旨在填充根佈局的main區域。

現在,無論何時我想展示其中一個子應用程序,我都不知道如何(或者,我沒有找到最滿意的方式)要求根視圖的showChildView的佈局/這些子應用程序的佈局。

到目前爲止,我想出了兩種方法(其中沒有一個是太棒了):

編輯:我添加了另一種方法在Q

  1. 的每個控制器上的結束子應用程序,觸發事件「application:show」在視圖中傳遞。只要收到消息
  2. 每當我啓動一個子應用程序,我將它傳遞給根應用程序實例,根應用程序正在監聽此事件和showChildView。每當子應用程序需要顯示自己,它會調用main區域

第一種方法是弱內showChildView,因爲它是完全異步的(發射後不管)。我想知道什麼時候我的應用程序顯示(附加到DOM),但再次依賴另一個事件看起來很麻煩

第二種方法更強大,但它很糟糕,因爲我當然不希望子應用程序應用程序的視圖負責自己在根佈局中的呈現。根應用程序知道得更好。

一些代碼如下儘量展示兩個思路:

// Approach #1 

// In the root app 
welcomeApp.on('app:show', (view) => { 
    rootApp.rootView.showChildView('main', view); 
}); 

// In the Welcome sub-app 
var Controller = { 
    show() { 
     app.trigger('app:show', new WelcomeView()); 
    } 
}; 

// Approach #2 

// In the root application 
const welcomeApp = new WelcomeApp({ 
    rootApp: this 
}); 

// In the Welcome sub-app 
var Controller = { 
    show() { 
     app.rootApp.rootLayout.showChildView('main', new WelcomeView()); 
    } 
}; 

編輯:1月12日

OK,挖一點,我發現我在想什麼的文檔中是正確的方法要做到這一點。這個想法是,根應用程序將偵聽來自子應用程序的命令。

所以,在我的根視圖,我將有:

this.channel.commands.setHandler("application:show", function(view) { 
    this.rootView.showChildView('main', view); 
}.bind(this)); 

在所有其他的子應用,我會(例如,在WelcomeView):

getController() { 

    const greet = function() { 
     this.channel.commands.execute('application:show', new WelcomeView()); 
    }.bind(this); 

    return { 
     greet: greet 
    }; 
} 

回答

1

個人而言,我不會告發」 t使用多個應用程序,這似乎只是解決了模塊被刪除的問題。您是否嘗試過使用帶有LayoutView的單個應用程序,每個組件或(模塊)的區域以及組件的基礎是單身JS對象,還是嘗試使用Backbone.Service來分割它。如果你使用多條路線,你可以看看Backbone.Routing,每條路線都是'頁面'的基礎'控制器'。

我發現大型木偶應用程序的輝煌架構是詹姆斯凱爾的Marionette Wires。這對可重用組件使用Service,對不同數據類型使用路由器/路由。

編輯

架構使用服務的另一種方式,但如果你不想根應用的區域顯示從子組件調用的方法,將導入實例化的應用到子組件和使用app.addRegions方法在子內添加區域。 EG

//app.js 
import { Application } from 'backbone.marionette'; 

const App = Application.extend({ 
    onStart() { 
    //doSomething(); 
    }... 
}); 

export const app = new App(); 

//submodule/service.js 
import { Service } from 'backbone.service'; 
import { SubmoduleController } from './controller'; 

const SubmoduleService = Service.extend({ 
    requests() { 
    show: 'show', 
    hide: 'hide' 
    }, 

    setup(options = {}) { 
    this.el = options.el 
    }, 

    start() { 
    this.controller = new SubmoduleController({ 
     el: this.el 
    }); 
    }, 

    show() { 
    this.controller.show(); 
    }, 

    hide() { 
    this.controller.destroy(); 
    } 
}); 

export const submoduleService = new SubmoduleService(); 

//submodule/controller.js 
import { Object as Controller, Region } from 'backbone.marionette'; 
import { View } from './view'; 
import { app } from '../app'; 

export const SubmoduleController = Controller.extend({ 
    initialize(options = {}) { 
    this.el = options.el; 
    this._addRegions(); 
    }, 

    _addRegions() { 
    const region = new Region({ 
     el: this.el 
    }); 

    app.addRegions({ 
     submoduleRegion: region 
    }); 
    }, 

    show() { 
    const view = new View(); 
    app.submoduleRegion.show(view); 
    }, 

    onDestroy() { 
    app.submoduleRegion.reset(); 
    } 
}); 

//main.js 
import { submoduleService } from './submodule/service'; 

const config = { 
    submodule: { 
    el: '#submodule'; 
    }, 
    ... 
}; 

submoduleService.setup(config.submodule); 
submoduleService.show(); 

用這種方式做一個小問題,就是該子模塊的區域需要它的元素時,它的區域的顯示方法被稱爲DOM存在。這可以通過在應用程序的根視圖上實現,其模板包含所有組件根元件,或者具有根子模塊 - 頁面或其他東西。

+0

這真是一個有趣的想法。我不知道Wires(感謝您的鏈接),我也沒有考慮使用服務。儘管如此,我仍然不確定他們是否能夠按照我已經佈置的方式來合適我的應用程序。我對Backbone非常有經驗,但我還沒有嘗試過Marionette,所以我甚至沒有考慮過Modules,因爲它們已經被棄用了。 我不喜歡通過無線電一起通話的「封裝」應用程序的想法。我們來看看我該如何使用這些服務! – Claudio

+0

我不喜歡Wires的東西,現在我已經挖掘了一點,就是服務調用'this.container.show'方法,這正是我的問題的關鍵。我不喜歡「孩子」調用父母的方法......我知道它基本上與發送消息相同,但因爲一切都是基於事件的,所以這件事情讓我困擾:) – Claudio