`

如何合理地规划一个应用程序

阅读更多

需要些什么?

除ExtJS库本身外,我们还需要两个文件:

  • applayout.html
  • applayout.js


先看看一份html文档,比较精简。并附有详细说明:

applayout.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="stylesheet" type="text/css" href="../extjs/resources/css/ext-all.css">
    <script type="text/javascript" src="../extjs/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="../extjs/ext-all-debug.js"></script>
    <script type="text/javascript" src="applayout.js"></script>
    <!-- 本地化的脚本引用在这里 -->
    <script type="text/javascript">
        Ext.onReady(myNameSpace.app.init, myNameSpace.app);
    </script>
    <title>Application Layout Tutorial</title>
</head>
<body>
</body>
</html>

开头的两行声明了文档的类型。程序可以不用doctype,但是这样的话浏览器可能默认其为Quirks怪僻类型,会导致处理跨浏览器这一问题上出现差异。


我们采用HTML 4.01 Transitional的文档类型,该类型在主流浏览器上支持得不错。当然,你也可以根据你的需求采用其它类型的doctype,但是记住别忘了要加上doctype

接着指定HTML头部的Content-Type。做这些事情其实很琐碎,但总是有益处。

然后引入EXT的样式,适配器和EXTJS本身。有两种版本的ExtJS:

  • ext-all.js - 不能直接阅读,加载时更快,用于产品发布
  • ext-all-debug.js - 便于阅读,开发阶段使用,

开发阶段的时候便需要引入debug的版本。


applayout.js这个文件就是我们的程序,紧跟着的是本地化的脚本,这里可以换成Extjs翻译好的版本

跟着我们开始分配事件句柄(event handler),使得在文档全部加载完毕后,程序就可以初始化(运行)。

下面的这一行:

Ext.onReady(myNameSpace.app.init, myNameSpace.app);

可这样说:当文档全部加载完毕,就运行myNameSpace.app的init方法,规定的作用域是myNameSpace.app。

然后是标题,头部的结尾,body(当前空)和结束标签。

applayout.js

/**
  * Application Layout
  * by Jozef Sakalos, aka Saki
  * http://extjs.com/learn/Tutorial:Application_Layout_for_Beginners_(Chinese)
  */
/**
------------------------------------------------
中文用户请注意:applayout.js 这个文件应该在编辑生成文件的同时强行定义为UTF-8编码才可以通过. 
------------------------------------------------
*/
// 填充图片的本地引用
Ext.BLANK_IMAGE_URL = '../extjs/resources/images/default/s.gif';
 
 
// 创建命名空间
Ext.namespace('myNameSpace');
 
// 创建应用程序
myNameSpace.app = function() {
    // 元素还没创建,未能访问
 
    // 私有变量
 
    // 私有函数
 
    // 公共空间
    return {
        // 公共的属性,如,要转换的字符串
        // 公共方法
        init: function() {
            alert('应用程序初始化成功。');
        }
    };
}(); // 程序底部
 
// 文件底部

文件最开始的几行是注释,说明该文件的主要内容、作者、作者相关的资讯。没有任何注释的程序也可以正常的运行,————但请记住:每次写的程序要容易给人看得懂的 Always write your application as if you would write it for another.当你回头看你几个月前写的代码,发现你根本不记得自己写过什么的时候,就会明白这个道理,并养成编码的好习惯。接着是要指向你服务器的填充图片,如不指定则默认extjs.com。每次运行程序的时候都访问extjs.com,不推荐这样,应该先修改这个常量值指向到本地。


现在自定义命名空间。将所有变量和方法都划分到一个全局对象下管理,这样的好处是避免了变量名冲突和由不同函数干扰了全局变量的值。名字(namespace)可按自己的方案选择。


整段代码的重点是,我们创建了 myNameSpace对象的属性app,其值是一个函数立刻运行之后的返回值。

如果运行我们的代码:

var o = function() {
    return {p1:11, p2:22};
}();

实际上我们创建了一个匿名函数(没有名字的函数),经过解释之后让它立刻运行(注意函数后面的())。最后将函数返回的对象(注意此时是一个object变量)分配到变量o。我们的程序便是这种思路去写的。

你可以把私有变量和私有函数直接定义在function和return这两个声明之间,但是请切记:此时不能访问任何html页面中的元素,那会导致错误,因为这段代码在加载时页面的head中就运行了,而这时候html页面中的其它元素还没有被加载进来。

另外一方面,函数init,是由匿名函数返回的对象的一个方法而已。它会在文档全部加载才运行。换言之整个DOM树已经是可用的了。

一切都还好吧~如果能正确运行 http://yourserver.com/applayout/applayout.html ,不出现什么错误的话将弹出一个对话框。

接下来是利用这个空白的模板,讨论本文的重点。

公开Public、私有Private、特权的Privileged?

让我们程序变得更有意思。在页面applayout.html的body标签中加入:

<div id="btn1-ct"></div>

空白的div会当作按钮的容器来使用。然后在applayout.js加入下来代码:

/**
  * Application Layout
  * by Jozef Sakalos, aka Saki
  * http://extjs.com/learn/Tutorial:Application_Layout_for_Beginners_(Chinese)
  */
 
//  填充图片的本地引用
Ext.BLANK_IMAGE_URL = '../extjs/resources/images/default/s.gif';
 
// 允许这个指南同时在Ext2.0 和1.1 上同时工作
Ext.Ext2 = (Ext.version && (Ext.version.indexOf("2") == 0));
 
// 创建命名空间
Ext.namespace('myNameSpace');
 
// 创建应用程序
myNameSpace.app = function() {
    // 元素还没创建,未能访问
 
    // 私有变量
    var btn1;
    var privVar1 = 11;
 
    // 私有函数
    var btn1Handler = function(button, event) {
        alert('privVar1=' + privVar1);
        alert('this.btn1Text=' + this.btn1Text);
    };
 
    // 公共空间
    return {
        // 公共的属性,如,要转译的字符串
        btn1Text: 'Button 1',
 
        // 公共方法
        init: function() {
            if (Ext.Ext2) {
                btn1 = new Ext.Button({
                    renderTo: 'btn1-ct',
                    text: this.btn1Text,
                    handler: btn1Handler
                });
            } else {
                btn1 = new Ext.Button('btn1-ct', {
                    text: this.btn1Text,
                    handler: btn1Handler
                });
            }
        }
    };
}(); //程序底部
 
// 文件底部

变量btn1privVar1私有的。 那意味着在程序外部他们是不能够被访问的,而且也不可见。私有函数btn1Handler也是同样道理。

另外一个方面,btn1Text是公共变量所以可以被程序外部访问或者是修改(我们稍后将会演示)。

函数init特权的,即是私有变量和公共变量两者都可以被它访问到。在本例中,公共变量this.btn1Text和私有函数btn1Handler都能够被特权函数init所访问。同时,相对外界来说,它也属于公共成员的一种。

Ok,运行看看。能看到左上角的按钮吗?很好,点击它。得到一个privVar1=11的警告。这说明私有函数能访问私有变量。

但是,在第二个alert中,this.btn1Text却是undefined,表示是未定义的,这不是我们期望的结果。原因是在handler内的this变量指向的是button而不是我们的myNameSpace.app .增加scope属性来指明thismyNameSpace.app

if (Ext.Ext2) {
    btn1 = new Ext.Button({
        renderTo: 'btn1-ct',
        text: this.btn1Text,
        handler: btn1Handler,
        scope:this
    });
} else {
    btn1 = new Ext.Button('btn1-ct', {
        text: this.btn1Text,
        handler: btn1Handler,
        scope:this
    });
}

刷新一下,可以了吧?

重写公共变量

applayout.js底部加入下列代码:

Ext.apply(myNameSpace.app, {
    btn1Text:'Taste 1'
});
 
// 文件底部

这代码是用来干什么的呢?首先它创建了我们的程序对象然后改变(重写)公共变量btn1Text的值。运行后将看到按钮上文字的变化。


把文本都放到公共变量,以便于以后的国际化翻译工作,而不需要修改程序的内部代码。

当然你也可以将其它的值例如尺寸、样式、等等的总之是可自定义的选项都放到公共变量中。免于在数千行代码之中为查找某个颜色而费劲。

重写(Overriding)公共函数

接着更改一下代码,让它读起来是这样的:

Ext.apply(myNameSpace.app, {
      btn1Text:'Taste 1'
    , init: function() {
        try {
            btn1 = new Ext.Button('btn1-ct', {
                  text: this.btn1Text
                , handler: btn1Handler
                , scope: this
            });
        }
        catch(e) {
            alert('错误: "' + e.message + '" 发生在行: ' + e.lineNumber);
        }
    }
});
 
// end of file

我们这里将init重写了一篇,主要是在原来代码的基础上加入异常控制,以便能够捕获异常。试运行一下看还有没有其它的变化?

嗯 是的,出现了btn1Handler 未定义的错误。这是因为新的函数虽然尝试访问私有变量但它实际是不允许的。正如所见,原init是特权函数可访问私有空间,但新的init却不能。之所以不能访问私有空间,是因为:禁止外部代码No code from outside,哪怕是尝试重写特权方法。

分享到:
评论

相关推荐

    Ext官方中文教程(可打包下载)

    如何合理地规划一个应用程序 如何本地化ext的教程 xtype的含义 扩展Ext中的组件 扩展与插件之间的区别 扩展Ext的新手教程 Ext的类继承 从源码生成Ext 基础用法: DomQuery基础 Ext中的事件 简述模板 模板...

    IIS 应用程序池回收问题

    在IIS中,应用程序池(Application Pool)是一个逻辑容器,用于隔离运行不同应用程序的进程,以确保一个应用的问题不会影响到其他应用。然而,应用程序池的回收有时会导致一些问题,特别是当涉及到用户会话(Session...

    IIS应用程序池假死解决

    应用程序池是IIS中的一种机制,用于隔离运行的Web应用程序,以确保一个应用程序的问题不会影响到其他应用程序。当遇到"IIS应用程序池假死"的问题时,这通常意味着应用程序池已经停止响应,无法正常处理请求,对网站...

    Lotus应用程序开发

    在深入探讨Lotus应用程序开发的过程中,我们首先需要理解其核心组成部分——Lotus Domino,这是一个集成了邮件服务、数据库管理、Web应用开发与部署的强大平台。本文将围绕标题“Lotus应用程序开发”及其描述,深入...

    iis应用程序池回收批处理

    应用程序池是IIS中的一个重要概念,它是一个独立的进程,用于隔离不同应用程序的运行环境,确保一个应用的问题不会影响其他应用。在长时间运行或内存资源紧张的情况下,管理员可能需要对应用程序池进行回收,以释放...

    C#关闭应用程序进程

    ### C#关闭应用程序进程 在C#编程语言中,关闭应用程序进程是一项常见但需要谨慎处理的任务。本篇文章将深入探讨如何使用C#来安全地...总之,在设计应用程序时,合理规划退出逻辑对于提高用户体验和软件质量至关重要。

    IIS应用程序池以及回收AppPool

    在IIS中,应用程序池(Application Pool)是一个关键概念,它隔离了不同应用程序之间的运行环境,确保一个应用的问题不会影响到其他应用。这样设计的主要目的是为了提高系统的稳定性和安全性。 **应用程序池的作用*...

    JAVA C/S架构应用程序

    在这个特定的应用程序中,我们看到的是一个基于Java编写的桌面客户端应用,它能够与Oracle数据库进行交互,执行基本的CRUD(Create, Read, Update, Delete)操作。这个应用是为初学者设计的,旨在帮助他们理解和掌握...

    WPF应用程序的入口

    通过合理地组织这两个核心组件,开发者可以创建出既功能强大又用户体验优秀的应用程序。 了解和掌握这些基本概念对于成功开发WPF应用程序至关重要。无论是对于初学者还是有经验的开发者而言,深入研究这些主题都...

    C#跨应用程序调用。项目可以启动其他程序获取输出

    在C#编程中,跨应用程序调用是一种常见的需求,它允许一个程序启动、控制或通信与其他已安装在系统上的程序。这种技术对于实现系统集成、自动化任务或是扩展应用程序功能非常有用。本文将深入探讨如何使用C#进行跨...

    wince6.0下可用应用程序

    Windows CE 6.0(简称...总之,WinCE 6.0作为一款嵌入式操作系统,有着丰富的开发和应用生态,开发者需要了解其特有的系统架构、开发工具、API以及优化技巧,才能充分利用这个平台,创造出高效且适应性强的应用程序。

    VB应用程序的界面设计

    VB应用程序的界面设计是一个复杂而细致的过程,涉及用户研究、初步规划、控件设计等多个环节。遵循Windows界面准则,合理安排控件位置,保持界面一致性,是设计成功用户界面的关键。通过这些步骤,可以创建出既美观...

    退出程序(当应用程序和源代码时不同)labvIEW

    然而,如果你将VI编译成独立的应用程序(.exe),运行这个应用程序后,若要完全退出,就需要执行退出程序的操作,因为此时的程序不再依赖于LabVIEW开发环境,而是作为一个独立的可执行文件运行。 在LabVIEW中,退出...

    应用程序设计实例.pptx

    在应用程序设计过程中,有几个关键步骤和概念需要理解。本文档主要涵盖了项目9的应用程序设计实例,包括设计分析、系统设计和编译应用程序等核心环节。下面我们将深入探讨这些知识点。 首先,设计分析是应用程序...

    一种基于Android应用程序的隐私权限合理性检测模型.pdf

    【Android应用程序的隐私权限合理性检测模型】 随着移动互联网的飞速发展,Android应用程序已经成为人们日常生活中不可或缺的一部分。然而,伴随着这种便利性,用户隐私安全问题日益突出。许多应用程序在未明确告知...

    应用程序自动更新

    在IT领域,应用程序自动更新是现代软件开发中的一个重要组成部分,它极大地提高了用户使用软件的便捷性和安全性。自动更新工具能够确保应用程序始终运行在最新版本,从而获取最新的功能、修复、安全补丁,以及性能...

    使用Delphi7创建Intraweb应用程序

    Intraweb则是用于构建基于Web的客户端/服务器应用程序的一个框架,它允许开发者使用Delphi的VCL组件来创建动态的、交互式的Web应用。本文将深入探讨如何使用Delphi7与Intraweb框架协同工作,创建高效、易维护的Web...

    gps应用程序设计.rar

    综上所述,GPS应用程序设计是一个涵盖广泛技术领域的项目,从硬件接口的利用到用户体验的优化,都需要开发者具备扎实的技术基础和敏锐的市场洞察力。通过对各个层面的深入理解和实践,才能开发出满足用户需求的高...

    安卓实现开机自动进入应用程序

    在安卓系统中,让应用程序在开机后自动启动可以提高用户体验,特别是对于那些需要后台服务或者希望用户一打开手机就能看到最新信息的应用来说。本篇将详细介绍如何在安卓中实现开机自启动应用程序,并附带相关代码...

    maximo 应用程序设计器 文档

    - **Maximo 应用程序设计器**是IBM Maximo Asset Management系统中的一个关键组件,用于帮助用户创建、修改和管理Maximo应用程序的界面及业务逻辑。 - 通过应用程序设计器,用户可以对Maximo系统的各种应用程序进行...

Global site tag (gtag.js) - Google Analytics