0

小さな Web アプリケーションを構築しようとしていますが、ページのさまざまな部分の間で通信する方法がわかりません。特定の機能を使用して、質問を示します。

私のページはすべて汎用ツールバーを使用しています。このツールバーは複数のページで使用されるため、独自の PHP ファイルに含まれています。

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

ツールバーにはログイン ボタンがあります。クリックすると、モーダル ログイン ダイアログが開きます (この場合は Facebook ログイン ダイアログ)。ユーザーがログインすると、そのユーザーの名前がツールバーに表示され、ログイン ボタンが「ログアウト」ボタンに置​​き換えられます。この動作はユーザーがどのページを表示していても同じであるため、モーダルでログインを表示し、ユーザー名/ボタンを適切に更新するように toolbar.js ファイルを作成しました。

ただし、ほとんどのページでは、ツールバーからログインまたはログアウトすると、メイン ページのコンテンツも更新する必要があります。ログイン状態が変化したときに、toolbar.php を含むすべてのページが何かをしなければならないことを保証することはできませんが、ほとんどの場合はそうなるでしょう。

同様に、その逆も可能です。特定のページには、ツールバーの外側に「ログイン」ボタンがある場合があります。これを使用する場合、ツールバーを更新する必要があります。

これを処理する最善の方法は何ですか?

現在の実装 - これはひどいかもしれません…</p>

toolbar.js では、基本的に、ユーザーがログインするたびに (およびログアウトに相当する) 関数「userSignedIn」を呼び出しています。toolbar.js は、これ自体を実装します (ボタンとユーザー名ラベルを更新する必要があります)。

次に、メイン ページ (mainPage.php と呼びましょう) に何か追加する必要がある場合は、この同じ関数を再利用して追加のアクションを「追加」します。そのページの読み込み時に、次のことを行います。

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

customUserSignedIn は、追加のアクションを実行する mainPage.js 内の関数です。逆の解決策はまだ実装していません (mainPage.php からサインインするには、toolbar.php を更新する必要があります)。

私はObjective-Cのバックグラウンドから来たと思いますが、メソッドの実装で「スーパー」を呼び出すことに似た何かを試みています。

4

2 に答える 2

1

これを行う 1 つの方法は、空の配列を初期化してコールバック関数とそれらを呼び出す sign 関数を保持することです。他の JavaScript の前に次のようにします。

var userSignedInCallbacks = [];

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

次に、ツールバーとメイン ページの js の両方が、適切なコールバックを配列に追加します。

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

最後に、ツールバーまたはメイン ページのいずれかのログイン アクションは両方とも を呼び出すだけuserSignedIn()です。

于 2013-03-30T01:03:47.430 に答える
1

これを行う 1 つの方法は、ページ内の異なるモジュール間の通信を処理するパブリッシャー/サブスクライバーパターンを使用して、すべてのモジュールがイベント インターフェイスでのみ結合されるようにすることです。

ここで非常に簡単な例を作成しました。ログアウト プロセスは処理しませんが、どのように構造化できるかを確認できます。

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);
});
于 2013-03-30T01:06:56.250 に答える