2015-05-08 45 views
0

想象一下,如果您願意,應用程序具有一些獨特的視圖/狀態 - 我們稱之爲遊戲。你有一個超世界屏幕,一個戰鬥屏幕,一個多人遊戲界面,或許有一兩個迷你遊戲。瞭解AMD:如何通過單向模塊關係處理響應流程

爲了說明方便,每個視圖之間沒有太多共同的代碼,所以它非常適合AMD--一箇中央控制器/調度器,並且每個遊戲狀態都分成一個單獨的文件/視圖。

dispatcher.core.js 
> overworld.view.js 
> battle.view.js 
> tournament.view.js 
> minigame.view.js 

輸入和鍵命令被路由到調度器,並滴入到當前活躍視圖,其進而根據需要操縱DOM。單向AMD關係,迄今爲止非常好。

我得到的東西是響應流。通過系統的API響應數據多種多樣,通常會同時影響多個視圖。考慮這種情況下:

  1. 用戶按下按鈕來移動
  2. 鍵命令被路由到地圖視圖爲移動動畫
  3. 地圖發送AJAX請求到服務器的運行結果
  4. AJAX返回「戰鬥開始」響應到調度
  5. 調度員告訴地圖視圖禁用本身,然後戰鬥以初始化

調度員是爲此設計 - 接受指導和分發。這似乎是明顯的選擇,不僅僅是讓觀點直接相互影響。

但是,這裏存在一個基本缺陷 - 一旦AJAX結果從視圖發送到調度程序,違反了調度程序和視圖之間的單向關係。您可以將調度程序用於AJAX回調,也可以指示調度程序爲您進行AJAX調用 - 但是無論哪種方式,視圖都需要引用調度程序的方式,據我瞭解,這違反了AMD的核心原則。對於我的生活,我無法弄清楚這將如何正確實施!

我的問題是這個 - 如何正確實施這樣的結構?這是AMD的限制,還是我誤解它在更深層次上的使用?


這個問題的目的是爲更一般的情況,但如果它影響答案可言,我分別使用要求和jQuery用於AMD和AJAX。

回答

1

這是AMD的限制嗎,還是我誤解它在更深層次上的使用?

AMD不以任何方式強加在一般對象實例之間單程關係。強烈建議避免(因爲即使這不是絕對要求)它是模塊之間的循環依賴。對於AMD而言,依賴關係的類型是,加載依賴關係。

可以肯定有模塊名爲dispatcher雲:

define(function() { 
    function Dispatcher(views) { 
     this.views = views; 
     for (var ix = 0, view; (view = views[ix]); ++ix) 
      view.init(this); 
    } 

    return Dispatcher; 
}); 

而且viewAviewB,那些結構是這樣的:

define(function() { 
    function View() { 
     // ... 
    } 

    View.prototype.init = function (dispatcher) { 
     this.dispatcher = dispatcher; 
    }; 

    // Etc... 

    return View; 
}); 

你的主要模塊,可以這樣做:

define(['dispatcher', 'viewA', 'viewB'], function (Dispatcher, ViewA, ViewB) { 

    var viewA = new ViewA(); 
    var viewB = new ViewB(); 

    var dispatcher = new Dispatcher([viewA, viewB]); 
}); 

以上內容僅供參考。這是可能的,而不是一個好設計的處方。無論如何,重要的是,就AMD而言,在對象之間進行循環引用是完全可行的。

+0

啊,我認爲這就是我沒有連接的東西 - 這是t他加載不能循環的依賴關係,而不是函數引用。謝謝! – CodeMoose

1

有沒有關於AMD限制在這裏;這完全是關於你自己模塊的設計。


處理此問題的常用方法是使用event-emitter

dispatcher可以直接在view調用方法,但view發出該dispatcher可以聆聽和迴應,消除了對循環引用的需要(如view不關心的地方去活動活動,所以它。不需要的dispatcher參考)

安裝到您的工作流程示例,它可能是這樣的:

  1. overworld曲目按鍵
  2. overworld動畫響應按鍵
  3. overworld發出 '移動' 爲dispatcher

    // overworld.view 
    this.emit('move', {data}); 
    
    // dispatcher 
    overworld.on('move', getMoveResult) // getMoveResult fires AJAX request 
    
  4. 響應事件告訴dispatcher它的時間戰鬥
  5. dispatcher更新的觀點

    overworld.hide() 
    battle.show()