写在开头:学Rails的过程中发现了这个用Ruby开发智能手机应用程序的开源框架Rhodes,一边学习,一边把官方文档翻译分享出来,希望也能帮到有需要的看客,有兴趣可共同学习研究。E文水平有限,纯分享,欢迎修正意见。
E文官方文档:http://docs.rhomobile.com
App结构
Rhodes程序生成器用“rhoes app”命令生成一个基本的应用程序。当指定model和actions时,它会生成子目录、控制器和模板文件。请关注Rhodes生成器相关文档以了解更多关于Rhodes文件结构的细节。
目录结构举例
举个例子,/sugar是手机版SugarCRM程序的根目录。根据应用程序的功能,这个根目录下会包含几个.erb文件。还有一个作为主登陆页面的index.erb文件。这个主登陆文件有特别的链接连到一些数据模式的控制器,并且它本身并没有任何相关联的特殊控制器。如果应用程序的控制器需要一个主登陆界面,推荐创建一个 model/controller/view文件夹并且用controller中的一个action来做主登陆界面。为了实现这个方式,需要在配置框架的配置文件中修改start_path属性。
Model/View/Controller
根据惯例,每一个Model文件都包含一个controller,下面是一个model类和view模板的描述。
Controller
开发者可以在controller中简单的定义一些方法来创建任意数量的controller action。每一个acion都关联一个url并且可以通过WebView control中的View调用url来执行这个action。WebView control是一个嵌入应用程序UI的web浏览器。
如果你有一个Account Model,那么在account_controller.rb文件中就会有对应的controller actions,例如:
从Vier list action中可以用url:“Account/list”来调用这个action。
每一个自动生成的model controller都有几个基本的actions用以执行对象基本的CRUD(create,read,update and delete)操作。这些actions的清单如下:
-
Index – 展示所有对象列表
-
New – 显示创建新对象的编辑表单
-
Ceate – 实现创建对象
-
Edit – 编辑已存在的对象
-
Update – 更新对象的属性
-
Show – 查看对象
-
Delete – 删除对象
系统遵循Rails脚手架模式为对象生成CRUD actions(以及关联URL路径),并且根据惯例生成“资源地图”来路由这些actions。
Model
在iPhone,Android和Windows Mobile中Rhodes使用Sqlite来存储本地数据。在Blackberry5.0以上版本中Rhodes默认使用Hsql。在Blackberry5.0和以上版本中也可以使用Sqlite或者Hsql。你也可以使用Rhom来存储和操作数据。Rhom是Rhodes的迷你ORM(关系数据库映射)。它提供了一个更简单的操作本地数据库的编程方法。
根据惯例, 可以通过文件名定位到model文件夹中的model类。比如一个名为“UserBase”的model,文件应该命名为“user_base.rb”
举一个在model中增加upper_name方法的例子:
你可以定义一个PropertyBag model或者FixedSchema models。在第一个例子中,model对象可以有任意数量的属性,开发者可以通过为一个属性指定值的方法飘逸的创建这些特性。固定模型更僵化并且这些对象的属性需要在编译时被定义。但是值得关注的是固定模型将需要更少的设备空间。请到Rhom章节了解更多细节。
视图(模板)
每一个controller action通常会关联一个视图模板。上文提到的.erb文件就是视图模板。Rhodes继承了Rails的命名惯例。
-
Index.erb – 数据model 对象列表
-
Edit.erb – 编辑对象
-
Show.erb – 展现对象的属性值
-
New.erb – 创建新对象
这些文件都是通过rhodes生成器创建的。在这些模板中,可以使用任何有效的HTML,JavaScript和Ruby代码,Ruby代码应被包含在标签 <% and %>中。请到对应章节查看更多关于ERB的信息。
在你的controller中使用render方法,可以将视图发送到浏览器。比如,若要展示list.erb,可以在controller中用下面调用语句:
Render :action => :list
Rhodes框架会加载、处理list.erb模板,并将执行HTML结果发送到浏览器。
AppApplication类
Rhodes框架引入Application类来协调应用程序的启动。这个类持续存在于程序运行的整个生命周期,并且会接触controller actions的所有请求。你可以将session数据存储在这里。可以用下面的代码来获取AppApplicaiton对象的实例:
AppApplication类在application.rb中的定义如下:
如果你在AppApplicaiton类中定义了下面几个方法,你就可能涉及到激活/解除激活/升级事件。
On_ui_created方法在application的UI创建(通常是程序启动)之后被调用:
On_ui_destroyed方法在application的UI销毁(通常是程序推出)之后被调用:
在iPhone中,当程序转到后台时就会调用On_ui_destroyed,当用户在后台关闭程序时(通过多任务UI),不会任何事件会发送到程序。所以如果你想保存应用程序的状态,你可以在On_ui_destroyed中实现,但是需注意的是-这里仅仅是保存-不要在这个方法中执行销毁UI的操作。
On_activate_app方法在程序激活后被调用。
On_deactivate_app方法在程序转到后台之前被调用。
on_reinstall_config_update 方法在程序被升级后调用。如果程序包包含的Rhoconfig有在终端中已修改的本地属性,冲突是一个哈希数组的冲突值(旧的本地值,新的升级值)。默认情况下本地值会被覆盖,但你可以用新值或者其它步骤来重新配置应用程序升级。
回调的顺序及他们出现的条件
看看应用程序的生命周期:
initialize -> 应用程序开始时被调用
on_ui_created -> 应用程序UI创建时调用
on_activate_app -> 当应用程序最前端显示时调用
现在程序在屏幕上是活动的和可见的。假定现在用户不知什么原因要切换到另一个应用程序(比如接听电话)或者明确的将程序切换到后台运行。
On_deactivate_app -> 当应用程序切换到后台时
在现在的场景下,程序还是可以再次激活的(激活时将调用on_activate_app)或者系统能销毁程序UI来释放一些内存(销毁时将调用on_ui_destroyed)。让我们看另一个场景,如果程序UI已经被销毁但是我们需要重新激活程序:
On_ui_destroyed ->当系统销毁程序UI时被调用
On_ui_created -> 仅在用户请求系统激活程序后被调用(如触摸屏幕上的程序图标)
On_activate_app -> 当程序转到后台运行时被调用
好了,现在用户选择完全从应用程序退出(在选择菜单项目“Close”和调用程序中的System.exit方法中任选一个方法)。让我们看一下这个场景的回调顺序:
On_deactivate_app ->首先,程序将被解除激活(在屏幕上变成不可见)
On_ui_destroyed ->然后,程序UI将会被销毁
Kernel.at_exit -> 所有通过Kernel.at_exit已注册的调用都将当作普通的Ruby被调用。
以上就是它的工作流程。重要的是需理解On_activate_app经常在On_ui_created之后被调用,On_deactivate_app经常在On_ui_destroyed之前被调用。
程序帮助
Rhodes框架定义了少数几个帮助方法。为什么我们只有少数几个帮助方法呢?因为Rhodes框架是为移动终端而设计的,移动终端的空间也是我们需要关心的,所以我们设法保持框架尽量的紧凑。
生成的应用程序会有几个帮助文件(看app/folder文件夹)。这些帮助文件不是框架的核心文件,你可以在需要的时候进行修改、删除和扩展。
Link_to
举例说明如何使用link_to方法:
link_to "Visit Other Site", "http://www.rhomobile.com/"
==> <a href="http://www.rhomobile.com/" >Visit Other Site</a>
link_to "Help", { :action => "help" }
==> <a href="/app/model/help" >Help</a>
link_to "Delete", { :action => "delete", :id => '{12}' }
==> <a href="/app/model/{12}/delete" οnclick="
var f = document.createElement('form');
f.style.display = 'none'; this.parentNode.appendChild(f);
f.method = 'POST'; f.action = this.href; f.submit();
return false;">Delete</a>
link_to "Show", { :action => "show", :id => '{12}'},
"style=/"height:4px;width:7px;border-width:0px;/""
==> <a href="/app/model/{12}/show"
style="height:4px;width:7px;border-width:0px;">Show</a>
link_to "Delete", { :action => "delete", :id => '{12}' },
"class=/"delete_link/""
==> <a href="/app/model/{12}/delete" class="delete_link"
οnclick="var f = document.createElement('form');
f.style.display = 'none'; this.parentNode.appendChild(f);
f.method = 'POST'; f.action = this.href; f.submit();
return false;/">Delete</a>"
link_to "Invite",:action => :invite,
:query => {:name=>'John Smith','address'=>"http://john.smith.com"}
==> <a href="/app/model/invite?
name=John%20Smith&address=http%3A%2F%2Fjohn.smith.com">
Invite</a>
Rul_for
举例说明如何使用url_for方法:
url_for '/some_url'
==> /some_url
当生成一个新的URL时,确实的值会用表单中的当前请求参数来加载。例如,如果在调用参数中未指定程序名称或model,它们将从请求中加载。
url_for :action => :index
==> /app/model
url_for :action => :create
==> /app/model
url_for :action => :new
==> /app/model/new
url_for :action => :show, :id => '{12}'
==> /app/model/{12}/show
url_for :model => :another_model,
:action => :show, :id => '{12}'
==> /app/another_model/{12}/show
url_for :controller => :another_controller,
:action => :show, :id => '{12}'
==> /app/another_controller/{12}/show
url_for :application => :another_app,
:model => :another_model, :action => :show, :id => '{12}'
==> /another_app/another_model/{12}/show
url_for :action => :create, :query =>
{:name => 'John Smith', 'address' => "http://john.smith.com"}
==> /app/model?name=John%20Smith&address=http%3A%2F%2Fjohn.smith.com
url_for :action => :show, :id => '{12}', :fragment => "an-anchor"
==> /app/model/{12}/show#an-anchor
错误处理(400,500)
Rhodes能显示以下错误页面:app/E400.erb和app/E500.erb
400错误出现在Rho::RecordNotFound 异常时(如搜索一个不存在的对象ID)
500错误出现所有其它的异常情况
用$! 或者 Rho::RHO.current_exception获取异常对象
RhoSupport类
Rho::RhoSupport.url_encode(url)
将特殊字符的URL编码成%XX
Rho::RhoSupport.url_decode(url)
将%XX的URL解码成特殊字符
跨平台支持文件
在跨平台的基础上,你可以选择其它文件覆盖任何“app”或“public”文件夹中的文件。
要做到这一点,需构造第二个文件,文件名标识对应平台名称。
例如,在Android平台需替换以下文件:
Default.css
Index.erb
你要做的就是增加下面两个文件:
default.android.css
index.android.erb
记住你必须要有一个基本的父文件用于替换为一个平台文件。
有效的平台名称有:
android
wm
bb
iphone