2013-03-30 82 views
0

我正在嘗試構建一個小型web應用程序,但我不清楚如何在頁面的不同部分之間進行通信。我將使用我的特定功能來演示我的問題。如何在包含另一個php文件時構造javascript

我的所有頁面都使用通用工具欄。由於該工具欄上的多個頁面中使用,它是在其自己的PHP文件,我包括使用

<?php include("../toolbar.php"); ?> 

工具欄包括登錄按鈕。點擊後,這將打開一個模式登錄對話框(在這種情況下,Facebook登錄對話框)。當用戶登錄時,他或她的名字顯示在工具欄中,並且登錄按鈕被替換爲「登出」按鈕。由於無論用戶在查看哪個頁面,此行爲都是相同的,因此我創建了一個toolbar.js文件以顯示模式中的日誌並適當地更新用戶名/按鈕。

然而,在大多數頁面,或縮小從工具欄需要同時更新主頁的內容記錄。我無法保證包含toolbar.php的每個頁面在登錄狀態發生變化時都必須執行任何操作,但大多數情況下都會這樣。

同樣,反過來也是可能的 - 某個頁面可能在工具欄外有一個「登錄」按鈕。當使用這個時,工具欄需要更新。

處理這個問題的最佳方法是什麼?

當前實現 - 這可能是可怕的......

在toolbar.js我基本上調用一個函數,「userSignedIn」,只要用戶登錄(和註銷等效)。 toolbar.js自己實現它(它需要更新它的按鈕和用戶名標籤)。

之後,如果主網頁(讓我們稱之爲它mainPage.php)需要什麼額外的,我是「上釘」的附加動作相同功能,使用重。在該網頁的加載,我做到以下幾點:

var originalUserSignedIn = userSignedIn; 
userSignedIn = function() { 
    originalUserSignedIn(); 
    customUserSignedIn(); 
} 

customUserSignedIn是內mainPage.js,我在那裏執行其他操作的功能。我還沒有實施相反的解決方案(從mainPage.php需要更新toolbar.php登錄)。

我猜從客觀-C背景的,我試圖一些類似的方法實現調用「超級」。

+0

爲什麼不使用小工具包,讓您的生活更輕鬆?另外,我會將所有的業務邏輯移到一個保證加載的地方。 – David

+0

謝謝。不幸的是我對任何工具箱或分離業務邏輯知之甚少(關於提供某些鏈接)? –

回答

1

一種方式來做到這一點是初始化一個空數組來保存回調函數和符號函數來調用它們,在任何其他的javascript:

var userSignedInCallbacks = []; 

var userSignedIn = function() { 
    for (var i = 0; i < userSignedInCallbacks.length; i++) { 
     userSignedInCallbacks[i](); 
    } 
} 

之後,工具欄和主頁JS將兩者只需添加自己的相應的回調數組:

userSignedInCallbacks.push(function() { 
    // ... 
}); 

最後,無論是工具欄或主頁在登錄的操作都將只是調用userSignedIn()。你可以這樣做

+0

這聽起來很酷。我仍然習慣於可以像這樣使用函數的想法(例如放置在數組中)。謝謝 - 會給它一個鏡頭並報告回來。 –

+0

您甚至可以將回調函數作爲函數的*屬性*,因爲函數是對象。例如,你可以做'var userSignedIn = function(){...}; userSignedIn.callbacks = []'。然後你只需引用'userSignedIn.callbacks'來引用該數組。 –

+0

本,有一個想法(在你的原始答案) - 這不會讓我的兩個組件有點太緊?例如,如果沒有工具欄,就不可能使用主頁面,因爲它會嘗試訪問userSignedInCallbacks數組,如果不使用工具欄,它將不存在?不是一個交易破壞者,但對你的想法感興趣。 –

1

一種方式是通過處理不同模塊之間的通信在你的頁面,讓每一個模塊的只是一個事件接口在連接在publisher-subscriber模式。

我創建了一個非常簡單的例子here。它不處理註銷過程,但您仍然可以看到事物的結構。

HTML

<div id="toolbar"> 
    <button class="login">Login</button> 
</div> 

<div id="another-section"> 
    <button class="login">Login</button> 
</div> 

<div id="login-dialog"> 
    <button class="login">Do login!</button> 
</div> 

JS

//in EventBus.js 
var EventBus = { 
    subscribers: {}, 
    publish: function (eventName) { 
     var args = Array.prototype.slice.call(arguments, 1), 
      subscribers = this.subscribers[eventName] || [], 
      i = 0, 
      len = subscribers.length, 
      s; 

     for (; i < len; i++) { 
      s = subscribers[i]; 

      s.fn.apply(s.scope, args); 
     } 

    }, 
    subscribe: function (eventName, fn, scope) { 
     var subs = this.subscribers[eventName] = this.subscribers[eventName] || []; 
     subs.push({ fn: fn, scope: scope }); 
    } 
}; 

//in toolbar.js 
function Toolbar(el, eventBus) { 
    var $el = this.$el = $(el), 
     $loginButton = $('button.login', $el); 

    $loginButton.click(function() { 
     eventBus.publish('userWantsToLogin'); 
    }); 

    eventBus.subscribe('userLoggedIn', function() { 
     $loginButton.html('Logout'); 
     //change button handlers to handle logout... 
    }); 
} 

//in another-section.js 
function AnotherSection(el, eventBus) { 
    var $el = this.$el = $(el), 
     $loginButton = $('button.login', $el); 

    $loginButton.click(function() { 
     eventBus.publish('userWantsToLogin'); 
    }); 

    eventBus.subscribe('userLoggedIn', function() { 
     $loginButton.html('Logout'); 
     //change button handlers to handle logout... 
    }); 
} 

//in main.js 
$(function() { 
    var $loginDialog = $('#login-dialog'); 

    $loginDialog.dialog({ autoOpen: false}); 

    $('button.login', $loginDialog).click(function() { 
     EventBus.publish('userLoggedIn'); 
    }); 

    EventBus.subscribe('userWantsToLogin', function() { 
     $loginDialog.dialog('open'); 
    }); 

    new Toolbar('#toolbar', EventBus); 
    new AnotherSection('#another-section', EventBus); 
}); 
+0

謝謝plalx。我正在慢慢地消化這一個,需要很多東西。 –

+0

是的,我知道嘿嘿,但這是值得的;)如果你尋找它,那裏有很多的庫來幫助你實現它。基本上,你的模塊通過實現觀察者模式的對象觸發事件,並且他們傾聽他們關心的事件。在我的例子中,工具欄和AnotherSection模塊有自己的登錄按鈕。當它被點擊時,他們通過EventBus對象觸發事件'userWantsToLogin'。應用程序監聽此事件並顯示對話框,然後觸發'userLoggedIn'事件,允許監聽模塊更新其狀態。 – plalx

相關問題