这些天由于公司需要开发一个类似CRM的会员管理系统,我的技术选型为 Extjs+Yii+Mysql实现,发现Extjs3.x后推出了Direct组件,可以很方便的将服务器端的方法暴露给客户端调用,非常方便,于是就有了整合Yii框架的想法。
说干就干,花了一天时间进行研究、实现代码,Yii的组件架构和OOP的特性,让我比较方便的就实现了这个目标:兼容RPC批量调用和正常的MVC页面流程。
具体实现了几个类:
- ExtApplication,是CApplication的继承类,覆盖了ProcessRequest方法,区分普通页面action和RPC调用action等。
- Controller,是CController的继承类,覆盖若干方法以调用ExtAction
- ExtAction,是CAction的继承类,用于执行RPC方法
- ApiAction,也是CAction的继承类,用于暴露服务器端方法
- ExtDirect_API和ExtDirect_CacheProvider这两个类是direct自带的类,稍作修改。
将以上类文件放入项目的protected/components下即可,然后修改入口文件index.php为:
<?php
// change the following paths if necessary
$yii=dirname(__FILE__).'/../yii-trunk/framework/yii.php';
$config=dirname(__FILE__).'/protected/config/main.php';
// remove the following lines when in production mode
defined('YII_DEBUG') or define('YII_DEBUG',true);
// specify how many levels of call stack should be shown in each log message
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);
require_once($yii);
require(dirname(__FILE__).'/protected/components/ExtApplication.php');
Yii::createApplication('ExtApplication',$config)->run();
然后修改 protected/views/layouts/main.php,加入extjs引用和代码:
<link rel="stylesheet" type="text/css" href="/ext3/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="/css/main.css" />
<script type="text/javascript" src="/ext3/adapter/ext/ext-base-debug.js"></script>
<script type="text/javascript" src="/ext3/ext-all-debug.js"></script>
<script type="text/javascript" src="/ext3/src/locale/ext-lang-zh_CN.js"></script>
<script src="<?php echo $this->createUrl('/site/api') ?>"></script>
<script type="text/javascript">
Ext.BLANK_IMAGE_URL = '/ext3/resources/images/default/s.gif';
var mk;
Ext.onReady(function(){
// Notice that Direct requests will batch together if they occur
// within the enableBuffer delay period (in milliseconds).
// Slow the buffering down from the default of 10ms to 100ms
Ext.app.REMOTING_API.enableBuffer = 100;
Ext.Direct.addProvider(Ext.app.REMOTING_API);
// provide feedback for any errors
Ext.QuickTips.init();
// turn on validation errors beside the field globally
Ext.form.Field.prototype.msgTarget = 'side';
});
</script>
这段代码“<script src="<?php echo $this->createUrl('/site/api') ?>"></script>”就是调用了接口页面,得到了服务器端暴露的方法列表,如:
Ext.ns('Ext.app'); Ext.app.REMOTING_API = {"url":"\/index.php","type":"remoting","actions":{"Site":[{"name":"DoLogin","len":1,"formHandler":true},{"name":"Logout","len":0},{"name":"updateBasicInfo","len":1,"formHandler":true},{"name":"getBasicInfo","len":2},{"name":"GetPhoneInfo","len":0},{"name":"getLocationInfo","len":1}],"Test":[{"name":"Index","len":0}]}};
然后这句:“Ext.Direct.addProvider(Ext.app.REMOTING_API);“就是向extjs注册了rpc的api。
这样准备工作就完成了。
接着添加apiAction的定义到 SiteController.php中:
/**
* Declares class-based actions.
*/
public function actions()
{
return array(
'api'=>array(
'class'=>'ApiAction',
),
);
}
然后在Controllers中定义普通action和rpc方法:
public function actionLogin()
{
$this->render('login');
}
/**
* @remotable
* @formHandler
*/
public function actionDoLogin($formPacket)
{
$model=new LoginForm;
// collect user input data
if(isset($formPacket['username']))
{
$model->username = $formPacket['username'];
$model->password = $formPacket['password'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login())
$output['success'] = true;
else
{
$output['success'] = false;
$output['errors'] = $model->errors;
}
return $output;
}
}
注意上面的 “
/**
* @remotable
* @formHandler
*/”
注释,表示DoLogin这个方法是可以远程调用的,且是表单处理方法,这里的备注可以在反射的时候用到。而且可以发现普通页面action和RPC的action的写法上的区别:一个是没有参数的,render页面或者直接输出内容的;一个是有参数的,然后有返回值的。
actionLogin对应的视图文件中就可以调用DoLogin方法来登录用户了:
var indexUrl = '<?php echo $this->createUrl('index') ?>';
Ext.onReady(function(){
function login(){
if(form.getForm().isValid()){
form.getForm().submit({
waitMsg: '正在登录,请稍候...',
waitTitle:'登录中',
success: function(form,action){
loginwin.hide();
window.location = indexUrl;
}
});
}
}
var form = new Ext.form.FormPanel({
baseCls: 'x-plain',
labelWidth: 55,
defaultType: 'textfield',
title: '<div style="padding:10px;text-align:center;font-size:22px; border-bottom:silver solid 1px; margin-bottom:5px;">会员管理系统</div>',
api: {submit: Site.DoLogin },
items: [{
fieldLabel: '用户名',
name: 'username',
allowBlank: false,
blankText: "请输入您的用户名",
anchor:'92%',
listeners: {
specialkey : function(field, e) {
if (e.getKey() == Ext.EventObject.ENTER) {
login();
}
}
}
},{
inputType: "password",
fieldLabel: '密 码',
allowBlank: false,
blankText: "请输入您的密码",
name: 'password',
anchor: '92%' ,
listeners: {
specialkey : function(field, e) {
if (e.getKey() == Ext.EventObject.ENTER) {
login();
}
}
}
}],
buttons: [{
text: '登录',
handler: login
},
{text: '重设', handler: function(){form.getForm().reset();}}
],
buttonAlign:'center'
});
var loginwin = new Ext.Window({
title: "管理登录",
width: 300,
height: 180,
modal: true,
draggable: false,
closable: false,
tools: [{id: "help", handler: function(){Ext.Msg.alert('帮助','输入您的用户名和密码登录系统。')}}],
layout: 'fit',
plain:true,
bodyStyle:'padding:5px;',
items: form,
resizable: false
});
loginwin.show();
});
注意FormPanel中的 “api: {submit: Site.DoLogin },”,这样表单的处理请求就自动被发送到了SiteController的actionDoLogin方法,其处理结果也自动返回给客户端了,是不是很方便?
以上涉及到的完整代码已附上,需要的朋友拿去吧,有问题别忘了反馈,一起改进完善。
效果截图:
以上截图表现的是如何处理表单,下面说说如何调用服务器端其他方法,如我们在SiteController中定义:
/**
* @remotable
* put your comment there...
* This method configured with len=2, so 2 arguments will be sent
* in the order according to the client side specified paramOrder
* @param Number $userId
* @param String $foo
* @return Array response packet
*/
function actiongetBasicInfo($userId, $foo){
return array(
'success'=>true,
'data'=>array(
'foo'=>$foo,
'name'=>'Aaron Conran',
'company'=>'Ext JS, LLC',
'email'=>'aaron@extjs.com'
)
);
}
/**
* Handler for client side form sumbit
* @formHandler
* @remotable
*
* @param Array $formPacket Collection of form items along with direct data
* @return Array response packet
*
*/
function actionUpdateBasicInfo($formPacket){
$response = array();
$email = $formPacket['email'];
if ($email == 'aaron@extjs.com') {
$success = false;
$response['errors'] = array(
'email'=>'already taken'
);
} else {
$success = true;
}
$response['success'] = $success;
// return form packet for demonstration/testing purposes
$response['debug_formPacket'] = $formPacket;
return $response;
}
接下来就可以在客户端js中这么调用:
var basicInfo = new Ext.form.FormPanel({
// configs for FormPanel
title: 'Basic Information',
border: false,
padding: 10,
buttons:[{
text: 'Submit',
handler: function(){
basicInfo.getForm().submit({
params: {
foo: 'bar',
uid: 34
}
});
}
}],
// configs apply to child items
defaults: {anchor: '-20'}, // provide some room on right for validation errors
defaultType: 'textfield',
items: [{
fieldLabel: 'Name',
name: 'name'
},{
fieldLabel: 'Email',
msgTarget: 'side',
name: 'email'
},{
fieldLabel: 'Company',
name: 'company'
}],
// configs for BasicForm
api: {
// The server-side method to call for load() requests
load: Site.getBasicInfo,
// The server-side must mark the submit handler as a 'formHandler'
submit: Site.UpdateBasicInfo
},
// specify the order for the passed params
paramOrder: ['uid', 'foo']
});
这样一来,这个表单的初始数据加载和提交,就都是RPC自动调用了,是不是很赞?呵呵
- 大小: 72.1 KB
- 大小: 71.2 KB
分享到:
相关推荐
Yii Framework API手册 英文原版
yii framework框架 + yii app模板(基本、高级)
Yii Framework 1.1.6 框架
Yii Framework是一个高性能的PHP5的web应用程序开发框架。通过一个简单的命令行工具 yiic 可以快速创建一个web应用程序的代码框架,开发者可以在生成的代码框架基础上添加业务逻辑,以快速完成应用程序的开发。
yii framework 中文完全手册
Yii是一个高性能的PHP5的web应用程序开发框架。通过一个简单的命令行工具 yiic 可以快速创建一个web应用程序的代码框架,开发者可以在生成的代码框架基础上添加业务逻辑,以快速完成应用程序的开发。
yii framework 1.1.14 chm文档,从官方html文档编译,展示效果很好.
PhpStorm6 创建yii framework项目全过程。
Yii采用严格的OOP编写,并有着完善的库引用以及全面的教程。从 MVC,DAO/ActiveRecord,widgets,caching,等级式RBAC,Web服务,到主题化,I18N和L10N,Yii提供了今日Web 2.0应用开发所需要的几乎一切功能。事实上...
Yii Framework 1.10的API手册
YiiFramework 最新最完善的YII框架
本Yii2 ExtJs5 RBAC项目基于PHP开发,包含83个文件,包括PHP源代码、PNG图片、Markdown文档、SQL脚本、GIT忽略...系统实现了Yii2框架下的ExtJs5前端界面和RBAC权限控制功能,界面友好,功能完善,适合用于权限管理。
yii framework 最全最新的中文手册
PHP实例开发源码—Yii Framework php框架.zip PHP实例开发源码—Yii Framework php框架.zip PHP实例开发源码—Yii Framework php框架.zip
Yii Framework 2.0 Where条件拼接 pdf 应该囊括 了大部分的查询示例,like ,not,...
Yii Framework 2.0 权威指南 pdf格式 中文高清离线版 有书签
yiiframework 纯中文手册 在官网的基础上翻译的更全面 更详细
Yii Framework v1.1.10类参考中文手册
2019年最近整理的YII Framework 2.0权威指南文档。在这里上伟希望能帮到大家。可以方便的在手机上,或没有网络的地方查看学习。