0

我正在尝试构建一个小型 Web 应用程序,但我不清楚如何在页面的不同部分之间进行通信。我将使用我的特定功能来演示我的问题。

我所有的页面都使用通用工具栏。由于这个工具栏在多个页面上使用,它在它自己的 PHP 文件中,我包括使用

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

工具栏包括一个登录按钮。单击后,将打开一个模式登录对话框(在本例中为 Facebook 登录对话框)。当用户登录时,他或她的名字会显示在工具栏中,并且登录按钮被一个“注销”按钮所取代。由于无论用户正在查看哪个页面,此行为都是相同的,因此我创建了一个工具栏.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

一种方法是在任何其他javascript之前初始化一个空数组以保存回调函数和调用它们的sign函数:

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

您可以做到这一点的一种方法是使用发布者 - 订阅者模式来处理页面中不同模块之间的通信,以便每个模块仅在事件接口上耦合。

我在这里创建了一个非常简单的示例。它不处理注销过程,但您仍然可以看到事物的结构。

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 回答