ajax mvc_AJAX MVC(可以这么说)

ajax mvc

ajax mvc

This is sort of a framework thing to create AJAX applications, based on the MVC design pattern. Yep, I have a lot of buzzwords here, I admit, but this shouldn't be taken too seriously. I was doing a bunch of small projects lately and I found myself using something like this little framework, without even thinking about it. Then I thought about it and I found that the scripts and the organization of them may resamble MVC a bit. So how does MVC fit when you mix things like thin and fatter client, HTML, JavaScript, XMLHttpRequest, PHP and CSS?

这是一种基于MVC设计模式创建AJAX应用程序的框架。 是的,我承认我在这里有很多流行语,但这不应该太当真。 我最近在做很多小项目,发现自己使用的是这样的小框架,甚至根本没有考虑过。 然后我考虑了一下,发现脚本及其组织可能会使MVC有点混乱。 那么,当您混合使用瘦客户端,胖客户端,HTML,JavaScript,XMLHttpRequest,PHP和CSS之类的东西时,MVC如何适应?

通常的AJAX应用程序流程 (Usual AJAX app flow)

What usually happens in an AJAX application is:

在AJAX应用程序中通常发生的是:

  1. you have an HTML page, styled with CSS

    您有一个使用CSS样式HTML页面
  2. you click on something

    你点击一些东西
  3. JS sends request to the server (to a PHP script)

    JS将请求发送到服务器(到PHP脚本)
  4. JS updates the original HTML page

    JS更新原始HTML页面

映射到MVC模式(Mapping to the MVC pattern)

OK, so what part of this process can be associated with a View, or a Model or a Controller? The Model is easy, it's the business logic, writing to a database and so on. This is the PHP script. The View? Obviously this is the HTML page and the CSS. But I'd like to think also about the JS that updates the page as part of the View. I mean it makes sense, it's updating the presentation part. Sometimes you even use innerHTML in the JS, but even if you use DOM, it becomes part of the HTML anyway. How about the Controller? Well, we have two controllers here. One that is on the server side, a PHP script that receives requests and "asks" the Model for the response. The other controller is on the client side, this is the JavaScript that decides what happens on a click of a button and sends an appropriate AJAX request to the PHP controller. Therefore I would consider any behavioural JS as part of the Controller, including attaching events as well as sending HTTP requests.

好的,那么该过程的哪一部分可以与视图,模型或控制器相关联? 该模型很简单,它是业务逻辑,是写入数据库等等。 这是PHP脚本。 风景? 显然,这是HTML页面和CSS。 但是我也想考虑将页面更新为View一部分的JS。 我的意思是说,这是对演示文稿部分的更新。 有时您甚至在JS中使用innerHTML,但是即使使用DOM,它仍然成为HTML的一部分。 控制器怎么样? 好吧,我们这里有两个控制器。 在服务器端的一个PHP脚本接收请求并“询问”响应模型。 另一个控制器在客户端,这是JavaScript,它决定单击按钮后会发生什么,并将适当的AJAX请求发送到PHP控制器。 因此,我会将任何行为JS视为Controller的一部分,包括附加事件以及发送HTTP请求。

AJAX MVC

Here's an illustration:

这是一个例子:

实际应用中(示例) (In action (example))

I went ahead and implemented a very simple application to prove the concept. It's just a blank styled HTML page with a button. The HTML page includes two JavaScripts responsible for behaviours (Controller) and page updates (View). The page also includes a few unrelated helper javascripts, in my case I'm using the YUI library. The JS Controller attaches an event to the button. Then when you click the button, the JS Controller sends a request to the PHP controller. The PHP controller (just a simple switch) figures out what was requested and calls the appropriate object of the business model. In my simplistic case, the abovementioned "model object" is just a simple function, but this can be easily built upon. The Model returns (JSON-encoded) response, in this case it's a list of installed PHP extensions. Now the response is received by the View JS and it updates the page. After that the View calls another function from the JS controller that attaches new events to the new content. (Yep, a little glitch here, maybe it would have been better if the Model's response is handled by the JS controller which in turn calls the JS view updater, but anyway this is easy to fix)

我继续并实现了一个非常简单的应用程序来证明这一概念。 这只是带有按钮的空白样式HTML页面。 HTML页面包括两个负责行为(控制器)和页面更新(视图)JavaScript。 该页面还包含一些无关的辅助javascript,就我而言,我正在使用YUI库。 JS控制器将事件附加到按钮。 然后,当您单击按钮时,JS控制器将请求发送到PHP控制器。 PHP控制器(仅是一个简单的开关)即可确定请求的内容并调用业务模型的适当对象。 在我的简单情况下,上述“模型对象”只是一个简单的函数,但是可以很容易地建立它。 该模型返回(JSON编码)响应,在这种情况下,它是已安装PHP扩展的列表。 现在,View JS收到了响应,并更新了页面。 之后,View从JS控制器调用另一个函数,该函数将新事件附加到新内容。 (是的,这里有一些小故障,如果模型的响应由JS控制器处理,而这又会调用JS视图更新程序,也许会更好,但无论如何这很容易解决)

目录布局 (Directory layout)

AJAX MVC dir

Here's the directory structure:

这是目录结构:

One might argue that it's better if you don't mix .js, .css and .php files in the same directory but the whole idea is open to interpretations anyway, it's just an illustration of the idea.

有人可能会说,最好不要在同一目录中混用.js,.css和.php文件,但是整个构想还是可以接受解释的,这只是该构想的一种说明。

该示例代码 (The code for the example)

We get to the fun part, the actual implementation. So we start with a simple .html page, the initial part of the view.

我们进入了有趣的部分,即实际的实现。 因此,我们从一个简单的.html页面开始,它是视图的初始部分。

This is index.html

这是index.html

<?xml version="1.1" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <title>Welcome</title>
  <link rel="stylesheet" href="../view/styles.css" type="text/css" media="all" title="Default styles" />
  <script language="javascript" type="text/javascript" src="../_extras/yui/build/yahoo/yahoo-min.js"></script>
  <script language="javascript" type="text/javascript" src="../_extras/yui/build/event/event-min.js"></script>
  <script language="javascript" type="text/javascript" src="../_extras/yui/build/connection/connection-min.js"></script>
  <script language="javascript" type="text/javascript" src="../view/updates.js"></script>
  <script language="javascript" type="text/javascript" src="../controller/behaviours.js"></script>
</head>
<body>
 
  Welcome to my app!
  <br />
  <form action="" method="post">
    <input type="button" name="b" id="thebutton" value="I'm a button, click me!" />
  </form>
  <div id="content">&nbsp;</div>
 
</body>
</html>

As you can see, nothing special, simply including the CSS styles, the YUI "extras" and two other javascripts - one part of the View and one that is part of the Controller.

如您所见,没什么特别的,仅包括CSS样式,YUI“ extras”和另外两种JavaScript-一种是View的一部分,另一种是Controller的一部分。

The Controller JS is responsible for attaching an event listener to the button.

Controller JS负责将事件侦听器附加到按钮。

This is an excerpt from the behaviours.js

这是来自behaviours.js的摘录

// the behaviour class
var behaviours = {
 
    phpcontroller: "../controller/switch.php?request=",
 
    // more behaviour.methods....
}
 
 
// initial page load, attach onload event(s)
YAHOO.util.Event.addListener(
    'thebutton', 'click', behaviours.theButtonClick);

Now when the user clicks the button, the method behaviours.theButtonClick() is executed. It fires a request to the PHP controller switch and says that the request type is "loadSomething":

现在,当用户单击按钮时,将执行behaviours.theButtonClick()方法。 它向PHP控制器开关发出请求,并说该请求类型为“ loadSomething”:

theButtonClick: function(e) {
  alert('Ouch! \n\nOK, I\'ll make a request for ya, buddy!');
  YAHOO.util.Connect.asyncRequest (
      'GET',
      behaviours.phpcontroller + 'loadSomething',
      {success: updates.writeContent}
  );
},

The PHP controller (controller/switch.php) receives the request, does a simple switch to validate the request type and then calls the appropriate (in my case just a simple) function from the business model. Here's the full switch.php code:

PHP控制器(controller / switch.php)接收请求,进行简单的切换以验证请求类型,然后从业务模型中调用适当的函数(在我的情况下只是一个简单的函数)。 这是完整的switch.php代码:

<?php
// is this a request?
if (empty($_GET['request'])) {
  die();
}
// get the business logic
include_once '../model/business.php';
 
// figure out the request
// and call the business logic object
switch ($_GET['request']) 
{
  case 'loadSomething':
    echo loadSomething();
    break;
  case 'loadSomeMore': // not used, example
    echo loadSomeMore();
    break;
}
?>

The function loadSomething() from the PHP model gets a list of installed PHP extensions, encodes them into JSON and sends them back. This is a full listing of the ../model/business.php

PHP模型中的函数loadSomething()获取已安装PHP扩展的列表,将其编码为JSON并发回。 这是../model/business.php的完整列表

<?php
function loadSomething() {
  $extensions = get_loaded_extensions();
  return '["'. implode('","', $extensions) . '"]'; 
}
?>

If you go back and look at the AJAX request, you'll see that on success, I call the updates.writeContent() method. The ../view/updates.js script contains stuff that updates the HTML of the original page, so its place is in the View part of the app. writeContent simply creates an HTML table with the results (the list of PHP extensions). Then I wanted to attach event listeners to this table just to change color, but it can be more than that. Attaching events is a job for the JS Controller, therefore a method of its class is called. Here's a full listing of updates.js:

如果回头查看AJAX请求,您会看到成功后,我调用了updates.writeContent()方法。 ../view/updates.js脚本包含用于更新原始页面HTML的内容,因此其位置位于应用程序的“视图”部分中。 writeContent只是简单地用结果(PHP扩展列表)创建一个HTML表。 然后,我想将事件侦听器附加到此表上只是为了更改颜色,但是它可以做得更多。 附加事件是JS Controller的工作,因此将调用其类的方法。 这是updates.js的完整列表:

var updates = {
 
  writeContent: function (xmlhttp) {
    if (!xmlhttp.responseText) {
      alert("I got nothing from the server");
    }
    var data = eval(xmlhttp.responseText);
    var write_to = document.getElementById('content');
    write_to.innerHTML = ''; // yeah, I know
    
    var html2dom_root = write_to;
    var table = document.createElement("table");
    var table_1_tbody = document.createElement("tbody");
    for (var i in data) {
      table_1_tbody_2_tr = document.createElement("tr");
      table_1_tbody_2_tr_1_td = document.createElement("td");
      num = 1 + parseInt(i);
      table_1_tbody_2_tr_1_td_1_text = document.createTextNode(num);
      table_1_tbody_2_tr_1_td.appendChild(table_1_tbody_2_tr_1_td_1_text);
      table_1_tbody_2_tr.appendChild(table_1_tbody_2_tr_1_td);
      table_1_tbody_2_tr_2_td = document.createElement("td");
      table_1_tbody_2_tr_2_td_1_text = document.createTextNode(data[i]);
      table_1_tbody_2_tr_2_td.appendChild(table_1_tbody_2_tr_2_td_1_text);
      table_1_tbody_2_tr.appendChild(table_1_tbody_2_tr_2_td);
      table_1_tbody.appendChild(table_1_tbody_2_tr);
    }
    table.appendChild(table_1_tbody);
    html2dom_root.appendChild(table);
    
    behaviours.updateTableBehaviour();
  }
}

(BTW, for the DOM part I'm used the help from my little tool html2dom to make my life a bit easier)

(顺便说一句,对于DOM部分,我使用了我的小工具html2dom的帮助使我的生活更轻松了)

And finally here's the rest of the JS controller (behaviours.js), the method behaviours.updateTableBehaviour() that adds an event listener to the new table and the trClick() that handles clicks on this table. On click, it justs changes the color of the underlying row.

最后是JS控制器的其余部分(behaviours.js),方法behaviours.updateTableBehaviour()(向新表添加事件侦听器)和trClick()(用于处理对该表的点击)。 单击时,它会更改基础行的颜色。

  trClick: function (e) {
    var target = (e.srcElement) ? 
      e.srcElement.parentNode : e.target.parentNode;
    if (target.tagName == 'TR') {
      if (target.className == 'tr-on') {
        target.className = '';
      } else {
        target.className = 'tr-on';
      }
    }
  },
  
  updateTableBehaviour: function () {
    var el = document.getElementById('content').firstChild;
    YAHOO.util.Event.addListener(
      el, 'click', behaviours.trClick);
  }

演示和下载 (Demo and downloads)

  • Demo - the live example

    演示-现场示例

  • Zipped demo - all the source code for the example

    压缩演示-示例的所有源代码

  • Template - the source code for the example but with the example part commented, so you can use it as a template for your next AJAX project. The only thing you need to do is to drop the YUI in the _extras/yui folder.

    模板-示例的源代码,但示例部分带有注释,因此您可以将其用作下一个AJAX项目的模板。 您唯一需要做的就是将YUI放在_extras / yui文件夹中。

Thank you for reading, any comments welcome!

感谢您的阅读,欢迎任何评论!

Tell your friends about this post on Facebook and Twitter

FacebookTwitter上告诉您的朋友有关此帖子的信息

翻译自: https://www.phpied.com/ajax-mvc/

ajax mvc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值