【问题标题】:Ajax loading for complex projects复杂项目的 Ajax 加载
【发布时间】:2012-01-07 01:14:45
【问题描述】:

我的问题实际上不是 ajax 加载本身,更多的是在没有 javascript 的情况下加载它的能力。我的意思是,当我基于 ajax-availability OR just 编写整个项目而不使用 ajax 时,我可以轻松应对。

//编辑:虽然阿伦德已经有了或多或少有效的答案,但同时“这个问题没有直接的答案”。但是,我希望看到开发人员针对像我这样的场景的其他一些方法!即使只是几个链接也能提供帮助!

基本上,我只是感到沮丧,在同一页面上对所有内容进行两次编码,以确保未启用和启用 Javascript 的用户都具有相同的体验。这很烦人,我一直想知道其他人是如何解决这个问题的。

当我更新两个依赖于相同变量的 div 时,它会变得混乱。这是一个例子:

非 js 版本

require 'classobject.class.php';
$another_var = 'something';
$class = new classobject($_POST['variable']); // just an example to show that this is dynamic - I'm aware of injection!
$function = $class->returnsth(); // returns 1

if(isset($_POST)) {
    echo '<div id="one">Module 1 says:'; $require 'module_one.php'; echo '</div>';
    echo '<br /><br />';
    echo '<div id="two">Module 2 says:'; $require 'module_two.php'; echo '</div>';
}

现在在module_two.phpmodule_two.php 中,我的代码执行方式不同,具体取决于$function 的返回变量。 喜欢:

if($function >= 1 && another_var != 'something') {
   // do stuff
}
else { 
   // do other stuff 
}

现在,由于重新加载很容易,当我想在 keyUp/enter/submit 上加载两个模块时,我基本上遇到了一些问题:

  • 我必须手动将 $_POST 变量发送到模块才能使用它们
  • 我必须重新执行该类及其方法,并在每个模块文件中为它们建立一个链接 (require_once)。
  • 由于模块中不存在 $another_var,我也必须将此变量发送到每个模块(例如使用 post),然后在使用它之前,我必须像“更改”它一样$another_var = $_POST['another_var'];

我觉得这有点烦人,我想知道你们是怎么做到的。我希望我的编码方式不会太傻,但我想不出另一种方式。可能很难与我的非常基本的示例相关联,但是将整个项目与代码一起带来太多了。 总而言之,我正在寻找一种更好的方法来编码和清理这个混乱 - 一定有办法!我考虑过会话,但为了兼容性我不想依赖它们也可以(如果有人不允许使用 cookie)。

如果您无法理解我通过这种组装代码的方式要完成的工作,我将解释我经常面临的一个场景(如果您已经了解,则不重要我的痛苦):

  1. 基本上我有我的index.php 页面,所有内容都在其中执行,包括html 正文和css 样式等。此页面需要一些变量,这些变量是从需要索引的页面设置的(例如我的示例中的 $another_var)。
  2. 现在也可以设置其他变量(例如从表单)。根据不同的类和方法加载新变量(数组),这些变量在我的模块中的 while 循环中使用,以回显所有内容。

希望这不是太抽象。考虑一个预订系统,其中一些变量是从您来自的页面(您想要预订的事件)设置的,然后用户设置更多的东西(时间跨度,一些偏好,......)。最后,它应该显示从数据库一直到最终结果的结果 - 你可以说用户逐步缩小结果范围。

【问题讨论】:

  • 我发现 progressive enhancementstrategy pattern 对于处理 ajax 和非 ajax 非常有帮助。
  • @Herbert 我仔细阅读了您的链接文章,并在 Google 上找到了更多内容。仍在为如何使用它来处理 ajax 和非 ajax 站点的具体想法而苦苦挣扎。您是否有一些代码可以让我更清楚您将如何做到这一点?

标签: php ajax jquery asynchronous page-refresh


【解决方案1】:

我用 PHP 写了这样的东西。我已经抽象了每个页面的渲染,因此我定义了一个$content 变量,然后是require('layout.php')$content 变量只是一个大的 HTML 字符串。

我写了一个 PHP 函数来判断请求是否是 AJAX。

非 AJAX 响应呈现布局,中间有 $content,b/t 页眉和页脚布局内容。

AJAX 请求基本上得到这个:json_encode(Array("content"=&gt;$content))。我使用 jQuery 从 JSON 响应中获取 HTML 并修改 DOM。使用 json_encode() 将处理 javascript 的字符串转义。

最后,我有效地对每个页面进行了 AJAX 化,而无需过度设计复杂的解决方案。

任何支持 AJAX 的浏览器也可以在新选项卡/窗口中打开链接以模拟非 AJAX 请求。 (或者也可以收藏/分享一个链接。)

【讨论】:

  • 抱歉,我不太了解您的做法。这与我的问题有什么关系,我有一个执行另一个脚本所必需的预定义 php 变量?
  • 这是对“我只是感到沮丧,在同一页面上对所有内容进行两次编码”的回应。我假设页面的顶部和底部没有改变,唯一需要为 AJAX 请求更新的是顶部和底部的东西。如果顶部和底部的内容可以表示为字符串变量,则它可以作为 AJAX 响应输出或卡在 HTML 之间,从而使页面顶部和底部成为一个完整的页面响应。因此,您不必编写所有代码两次。
  • 您的假设是正确的,但我认为您误解了我的问题(无意冒犯,要准确掌握我想要的内容可能并不容易)。基本上我的“编码两次”声明是指我在登录页面上设置了一些数组/变量等,没有ajax也没问题,但是当我用ajax加载时,我必须再次传递它们/执行一些方法和他们的参数。\
【解决方案2】:

您的问题没有直接答案,但有一些值得深思的地方。

关注点分离 您可以考虑是否可以将业务逻辑和布局逻辑分开。通常,使用模板引擎可以对此有很大帮助。我对例如 Twig 或 Smarty 有过积极的体验(前段时间,不知道他们现在如何衡量)。它要求您以(较少线性)但更合乎逻辑的方式编写代码。

像关注点分离这样的 OOP 的典型示例可能是这样的:

$this->setParam('Myparam','myvalue');

if ($this->isAjax())
{
    $this->setTemplate('ajax.php');        
    $this->setLayout(false);
} else {
    $this->setTemplate('normal.php');
    $this->setLayout('Mylayout');
}

return $this->render();

这是一种富有想象力的情况,可以在许多 MVC 之类的应用程序和框架中找到。主要思想是您应该有可能将布局与数据分开。我建议查看一些现代框架以获取灵感(如 symfony、codeigniter、zend 框架)。

词汇表/解耦 PHP 应用程序中常用的概念 这是可以使用的概念的快速列表。

php 中的 mvc 示例: http://www.phpro.org/tutorials/Model-View-Controller-MVC.html

注意:我不太喜欢这个实现。我更喜欢现有的框架。我确实喜欢本教程的全部解释。例如。对我来说,这个链接是用来学习的,不是用来实现的。

Silex 对于一个简单的解耦 php 微框架,我真的会推荐 symfony2 的 silex。它易于实现和学习,但包含此处描述的主要概念;并使用所有 php 5.3+ 的好东西,例如命名空间和闭包。

见:http://silex.sensiolabs.org/

前端控制器模式 您的代码只有一个,而且只有一个入口点。我通常只有一个,而且你的申请中只有一个点。通常前端控制器将请求“分派”到应用程序的其余部分

http://en.wikipedia.org/wiki/Front_Controller_pattern

路由

路由系统通常与前端控制器模式结合使用。它基本上描述了哪个 URL 连接到哪个模块/控制器。这允许您在不更改 URL 的情况下更改人们访问您的应用的方式。

见:https://stackoverflow.com/questions/115629/simplest-php-routing-framework

控制器

控制器是应用业务逻辑的地方。从数据库中获取数据、检查权限、设置模板、设置布局等(尽管如果单独关注太大,这也会移到控制器之外)。

型号 模型基本上是使用管理数据库的层。这可以是一个简单的类,您可以在其中移动所有 mysql_* 函数,也可以是一个功能齐全的 ORM。主要理念是所有与在数据库中获取和放置信息相关的逻辑都是分开的。

更上一层楼:ORM 应用程序中经常使用的方法是对象关系模型,这些将 SQL 记录“映射”到 PHP 对象。 Doctrine 和 Propel 是其中两个精心设计的库。我在开发过程中严重依赖这些系统。从这个意义上说,学说或推进部分将代表模型层。

查看: 视图通常包含一个模板引擎。一些使用普通的 PHP 作为模板,其他的,比如 symfony 创建一个单独的范围来放置变量。关于什么是最好的,有很多讨论和意见,其中一个就在 stackoverflow 上:

我喜欢的: - 树枝:http://twig.sensiolabs.org/ - sf模板:http://components.symfony-project.org/templating/ - 聪明的:http://components.symfony-project.org/templating/

解耦机制:

  • 基于事件的系统 使用您的事件可以帮助分离代码。例如,如果您想在保存记录后发送电子邮件,事件是一个很好的解决方案;一般来说,模型不必了解电子邮件。因此,事件是连接它们的一种方式:您可以让您的 -email-send-class 监听某些记录,以便它们发送正确的电子邮件。 (也许您希望您的电子邮件从您的控制器发送,这可能是个人喜好问题)。

  • 依赖注入 在 PHP 中使用 OOP 代码时,许多依赖于运行单例类(配置等)。从 OOP 的角度来看,这可能被认为是不好的,因为它很难测试,而且像这样运行依赖项也不是很优雅。依赖注入是一种来自 Java 的模式,现在在较新的框架中使用来解决这个问题。可能有点难以理解,但您会看到它在几个新框架中重新出现。

php中的依赖注入:Dependency Injection in PHP 5.3

框架:

这些方法很多都很难,或者需要自己去实现很多工作。许多人会为此建立一个框架。您可能需要也可能不需要框架。您可能想要也可能不想要一个框架,这是您的选择。但是学习框架如何做到这一点仍然很有用,而不是尝试自己重新发明轮子。

无框架的php框架:https://stackoverflow.com/questions/694929/whats-your-no-framework-php-framework

好习惯:https://stackoverflow.com/questions/694246/how-is-php-done-the-right-way

值得一看的框架(恕我直言):CodeIgniter、Kahona、CakePHP、Symfony (1.4/2.0)、Silex、Zend Fanework、Yii。还有更多,每个都有自己的忠实粉丝和仇恨者。

【讨论】:

  • 从理论上讲,这听起来像是我正在寻找的东西。因为我自己编码和设计,我从来没有真正考虑过使用模板引擎,但也许这是我应该研究它的时候了。会看看的,谢谢!但是在你的“虚构”例子中,这对我来说是不是意味着我基本上写的是一样的,只是把它分开更多/更好?
  • 这更像是一个例子,很多类似 MVC(模型、控制器、视图)的应用程序是如何工作的;但它需要更多的抽象编码。 (自己做的事情并不总是很令人兴奋)。我会为您添加一些指向该帖子的链接作为一些背景信息。
  • 我只想重申阿伦德所说的话。这个问题确实需要大约 2,000 行源代码才能回答。不过,基本概念是您应该能够设置一个环境,在该环境中处理数据的代码同时用于 ajax 和非 ajax 请求,并且只有最终输出(HTML 与 JSON)发生变化。确切地说,它是如何完成的,这实际上是个人品味的问题。研究一下 Zend/etc 以获得灵感。不要将自己限制在 PHP 上!查看 Ruby on Rails 或 iPhone 的 UIKit,它们都是 MVC 框架,比我所知道的任何 PHP 框架都要好,充满了可以借鉴的好技术。
  • 一个好的开始是确保每个表都有一个专门用于查询的“模型”类。并为您的 HTML 使用模板(您可以将 PHP 用于模板文件,但它们应该专门用于生成 HTML,并且不包含比基本 if 语句更复杂的任何内容),然后您就有了一个“控制器”类,它的工作是绑定所有它在一起。他们不做任何数据库查询,也不打印任何 HTML。在非常复杂的代码中,每个表可能有多个类,以及数十甚至数百个控制器类,模板文件也可能会将它们的一些工作推送到类中。
  • 我认为您应该使用相同的控制器,因为使用 ajax 完成的任何重要事情通常也需要在没有 ajax 的情况下才能实现。因此,它将有很多交叉。我只想在您的控制器“isAjaxRequest”中有一个布尔值,您可以随时查询以针对任何特定于 ajax 的内容执行简单的 if 语句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-28
  • 1970-01-01
  • 2010-11-22
  • 1970-01-01
  • 2013-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多