简体   繁体   English

如何在包含另一个php文件时构建javascript

[英]How to structure javascript when including another php file

I am attempting to build a small web application but I'm not clear how to communicate between different parts of the page. 我正在尝试构建一个小型Web应用程序,但我不清楚如何在页面的不同部分之间进行通信。 I will use my specific functionality to demonstrate my question. 我将使用我的特定功能来演示我的问题。

All of my pages use a generic toolbar. 我的所有页面都使用通用工具栏。 Since this toolbar is used on multiple pages, it is in its own PHP file, which I include using 由于此工具栏用于多个页面,因此它位于自己的PHP文件中,我使用它

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

The toolbar includes a log in button. 工具栏包含登录按钮。 When clicked, this opens a modal login dialog (in this case the Facebook login dialog). 单击时,将打开模式登录对话框(在本例中为Facebook登录对话框)。 When a user logs in, his or her name is displayed in the toolbar, and the log in button is replaced by a 'logout' button. 当用户登录时,他或她的名字将显示在工具栏中,登录按钮将被“注销”按钮替换。 Since this behavior is the same no matter which page the user is viewing, I created a toolbar.js file to display the log in modal and update the username/button appropriately. 由于无论用户正在查看哪个页面,此行为都是相同的,因此我创建了toolbar.js文件以显示模态中的日志并相应地更新用户名/按钮。

However, on most pages, logging in or out from the toolbar needs to also update the contents of the main page. 但是,在大多数页面上,登录或退出工具栏还需要更新主页面的内容。 I can not guarantee that every page that includes toolbar.php will have to do anything when the log in status changes, but most will. 我无法保证每个包含toolbar.php的页面在登录状态发生变化时都必须执行任何操作,但大多数页面会更改。

Similarly, the reverse is possible - a certain page might have a 'log in' button outside the toolbar. 类似地,反过来也是可能的 - 某个页面可能在工具栏外面有一个“登录”按钮。 When this is used, the toolbar needs to update. 使用它时,工具栏需要更新。

What is the best way to handle this? 处理这个问题的最佳方法是什么?

Current implementation - this might be awful… 目前的实施 - 这可能很糟糕......

In toolbar.js I am basically calling a function, 'userSignedIn', whenever the user logs in (and an equivalent for log out). 在toolbar.js中,我基本上在用户登录时调用一个函数'userSignedIn'(以及注销的等价物)。 toolbar.js, implements this itself (it needs to update its button and user name label). toolbar.js,实现它本身(它需要更新其按钮和用户名标签)。

Then, if the main page (lets call it mainPage.php) needs to anything additional, I am re-using this same function to 'tack on' the additional actions. 然后,如果主页面(让我们称之为mainPage.php)需要额外的任何东西,我将重新使用相同的功能来“粘贴”其他操作。 On load of that page, I do the following: 在加载该页面时,我会执行以下操作:

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

customUserSignedIn is a function within mainPage.js, where I perform the additional actions. customUserSignedIn是mainPage.js中的一个函数,我在其中执行其他操作。 I have not yet implemented a solution for the opposite (sign in from mainPage.php needs to update toolbar.php). 我还没有实现相反的解决方案(从mainPage.php登录需要更新toolbar.php)。

I guess coming from an objective-C background, I am attempting something analogous to calling 'super' in a method implementation. 我猜想来自一个Objective-C背景,我正在尝试类似于在方法实现中调用'super'的东西。

One way to do it is to initialize an empty array to hold callback functions and the sign function to call them, before any of the other javascript: 一种方法是在任何其他javascript之前初始化一个空数组来保存回调函数和sign函数来调用它们:

var userSignedInCallbacks = [];

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

Then, toolbar and main page js will both just add their appropriate callbacks to the array: 然后,工具栏和主页js都会将相应的回调添加到数组中:

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

Finally, the login actions in either the toolbar or main page will both just call userSignedIn() . 最后,工具栏或主页中的登录操作都将只调用userSignedIn()

One way you could do this is by using the publisher-subscriber pattern for handling communications between different modules in your page so that every modules is only coupled on an event interface. 实现此目的的一种方法是使用publisher-subscriber模式处理页面中不同模块之间的通信,以便每个模块仅耦合在事件接口上。

I created a very simple example here . 我在这里创建了一个非常简单的例子 It doesn't handle the logout process but you can still see how things could be structured. 它不处理注销过程,但您仍然可以看到事情的结构。

HTML 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 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);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM