本教程基于Ext的模板引擎展开详述,亦是对 Shea Frederick“模板入门教程一文的补充。假设读者已经初步接触过模板(Templates,和格式化函数的基本语法为“{VARIABLE:[(可选的参数)]}”

正式开始

假设我们打算从一变量中,打印出内容,但当中的内容有可能会占用过多的空间。对于这种情况,通过的办法是对该内容截取,限制在50个英文字符内,然后做成连接让用户点击后观察全文。函数"ellipsis" 的功能正是这样,可限制在任意字符数内。另外,在截取字符串的后面,该函数还会加上“...“,以示实际的内容还有更多。

一个模板如下示

var myTpl = new Ext.Template('
{content:ellipsis(50)}
Read More
');

通过处理,其中有47个字符是属于内容本身的,另外三个字符是”...“,一共50个字符。

这是一份可用于模板格式化函数的列表:

·     ellipsis(length) - 对大于指定长度部分的字符串,进行裁剪,增加省略号(“...”)的显示。适用于只显示前N位的字符,然后提供详细页面的场合。

·     undef -检查一个值是否为underfined,如果是的转换为空值

·     htmlEncode - 转换(&, <, >, and ') 字符

·     trim - 对一段文本的前后多余的空格裁剪

·     substr(start, length) - 返回一个从指定位置开始的指定长度的子字符串。

·     lowercase - 返回一个字符串,该字符串中的字母被转换为小写字母。

·     uppercase - 返回一个字符串,该字符串中的字母被转换为大写字母。

·     capitalize - 返回一个字符串,该字符串中的第一个字母转化为大写字母,剩余的为小写。

·     usMoney - 格式化数字到美元货币。如:$10.97

·     date[(format)] - 将一个日期解析成为一个特定格式模式的日期。如日期字符串不输入,默认为//

·     stripTags - 剥去变量的所有HTML标签

您亦可以创建自定义的格式化函数,具体做法是,在模板的实例上加入新的方法,继而在模板上调用,格式化的函数应该像这样的:{VARIABLE:this.}"

这是一个简单的实例,对模板实例加入一个"yesNoFormat "的新函数。yesNoFormat ColdFusion转换”truthy“函数相类似 ,如果是真的输出"Yes",假的输出"No"

var testCustomTpl = new Ext.Template('
User: {username} IsRevoked: {revoked:this.yesNoFormat}
');
testCustomTpl.yesNoFormat = function(value) {
              return value ? 'Yes' : 'No';
};                          
testCustomTpl.append(document.body, {username: 'aconran', revoked: 1});                              

下一步

关于怎么学好EXT这个框架我的看法是,在您熟悉的IDE中打开源码进行阅读。保证阁下一定会收获不少技巧和写代码的好习惯,而且极有可能发现新的大陆,还是没有归档的。熟悉模板Templates的简单用法和格式化功能后,就可进入下一步的学习:MasterTemplates MasterTemplates提供了处理子模板的功能,以方便从数据库循环数据,同时亦包含模板(Templates)的所有功能。

事件处理

在Javascript中,你将不得不经常进行事件的处理。这有时很难顺利进行,因为你需要进行不同的跨浏览器标准化事件处理。而ExtJs使得处理事件变得非常容易,有时候甚至还富于乐趣(!)。

非常基础的例子

想象一下这样一个例子,当用户点击一个链接时,你想向他显示一则警告信息。请继续往下看,因为在开始处理事件前你也许想知道更多。

var el = Ext.get('somelink');

el.on('click', function(){

    alert('you click on a link');

});

注意,在这里我们使用了一个匿名处理函数。另外,你应该在DOM初始化后才执行上述代码(使用Ext.onReady()方法)

处理函数的作用域

好了,我们刚刚学习了最基础的事件处理。让我们看看其他一些我们能做的事。默认情况下,处理函数内的作用域是你绑定事件的元素。

var el = Ext.get('somelink');

el.on('click', function(){

    alert(this.id); // 这里将显示'somelink'

});

注意this不是Ext Element对象。如果你想使用Ext的方法你必须使用"var el = Ext.get(this);"

但如果我们想要改变处理函数内的作用域呢?你可以把那个对象作为作用域参数。

function onClick = function(){

    alert(this.someProperty); // 这里将显示'someValue'

};

 

var scope = {

    someProperty : 'someValue'

}

 

var el = Ext.get('somelink');

el.on('click', onClick, scope);

提示:更多关于作用域的信息请参见这里

传递参数

在前面的例子中我们看到了如何改变处理函数内的作用域。但如果我们仍然想访问(与之相绑定的)元素呢?我们可以使用传递给处理函数的参数来进行操作。

function onClick = function(ev, target){

    alert(this.someProperty); // 这里将显示'someValue'

    alert(target.id); // 这里将显示'somelink'

};

 

var scope = {

    someProperty : 'someValue'

}

 

var el = Ext.get('somelink');

el.on('click', onClick, scope);

如你所见,在这个例子中我们使用了第二个参数(target)。第一个参数是Ext Event对象,我们可以使用此对象来做很多事情。

 

类设计

Javascript与其他的面向对象语言不同,如C++,Java或PHP等。它并不是基于类的,而是基于原型的一种语言。

对象创建

在Javascript中创建一个类是非常容易的:

var myObject = {

 aVar: 15,

 aMethod: function() {

    alert("I'm a method of the object myObject." + "aVar: " + this.aVar);

 }

}

你不必通过定义一个类然后实例化该类来创建一个对象。我们在这里使用了一个对象构造器。它满足了使用单个对象的场合。如果我们需要使用同一个类型的多个对象,我们必须使用一个构造器函数和new关键字。

使用构造器函数

在Javascript中没有类的概念,但是构造器是存在的。你可以编写一个函数,然后通过new关键字来创建一个对象。

// 首先,我们为我们的类定义一个空的构造器

function myClass() {

 this.aVar = 15;

 this.aMethod = function() {

    alert("I'm a method of the object myObject.");

 }

}

 

// 创建类的实例

var A = new myClass();

 

// 显示 15

alert(A.aVar);

 

// 第二个实例

var B = new myClass();

方法共享

你必须使用prototype对象:

// 我们定义了一个prototype对象的一个方法

myClass.prototype.sharedMethod = function() { alert("I'm a shared method") }

 

// 显示我们的信息

A.sharedMethod();

 

// 相同的信息

B.sharedMethod();

There is no method named sharedMethod in the myClass definition. Javascript looks for a method with this name in the prototype object of myClass and calls it if it exists. 在myClass定义中并没有一个名为sharedMethod的方法。Javascript会在myClass相关联的prototype对象中寻找与该方法名相同的方法,如果存在的话,Javascript则调用该方法。

 

表单组件入门

我建议下载用于这个例子的一段程序,这样可能对你有一些帮助。你也可以找一个有效的例子

表单体

首先要做的第一件事就是创建一个表单体,这相当于在HTML中书写一个 <form></form>标识。

var form_employee = new Ext.form.Form({
               labelAlign: 'right',
               labelWidth: 175,
               buttonAlign: 'right'
});

创建表单字段

表单示例由nametitlehire_dateactive四个表单字段构成。开头的两个表单字段nametitle,只是简单的文本字段,我们会用TextField方法来创建它们。

重要的配置选项是name,定义该选项与HTML中定义一个表单字段名几乎一样。

var employee_name = new Ext.form.TextField({
               fieldLabel: 'Name',
               name: 'name',
               width:190
});
 
var employee_title = new Ext.form.TextField({
               fieldLabel: 'Title',
               name: 'title',
               width:190
});

跟着的hire_date字段是一个日期字段,我们会用DateField方法来创建,它会为我们弹出一个别致的日期选择器来让我们选择日期。

format
配置选项被用来为PHP指定日期格式标准(PHP的日期格式)。日期格式字符串的调整须与你所用的日期格式相匹配。

var employee_hire_date = new Ext.form.DateField({
               fieldLabel: 'Hire Date',
               name: 'hire_date',
               width:90,
               allowBlank:false,
               format:'m-d-Y'
});

最后一个表单元素active是一个布尔值,我们使用Checkbox方法来创建。

var employee_active = new Ext.form.Checkbox({
               fieldLabel: 'Active',
               name: 'active'
});

完成表单

现在,我们把表单里的所有表单字段加入到fieldset中去。当然了,如果你想在fieldset的外面进行,可以选择使用add方法。

form_employee.fieldset(
               {legend:'Employee Edit'},
               employee_name,
               employee_title,
               employee_hire_date,
               employee_active
)

最后,最不能少的就是submit按钮,它与一小段点击时进行错误检测的代码块一起被addButton方法加进来。调用render方法,传入div标识的id,然后在网页的div里把表单显示出来。

form_employee.addButton('Save', function(){
               if (form_employee.isValid()) {
                              Ext.MessageBox.alert('Success', 'You have filled out the form correctly.');         
               }else{
                              Ext.MessageBox.alert('Errors', 'Please fix the errors noted.');
               }
}, form_employee);
 
form_employee.render('employee-form');

下一步

虽然本教程让你懂得了如何去创建一个表单,但创建出来的表单什么事情也干不了。就像一部没有引擎的小汽车——它看起来可能很漂亮,但不能让你走得更远。

 

为一个表单填充或提交数据

这个教程使用了在表单入门教程中使用过的 雇员信息编辑表单。如果你仍然不熟悉如何创建一个表单,你可以首先看一下这个例子。我建议下载用于这个例子的一段程序,这样可能对你有一些帮助。你也可以找一个有效的例子

我们将经历使用表单的整个过程,从最初的从服务器获取数据填入表单,到将数据返回给服务器。在后端我使用PHPMySQL, 然而这个例子对于PHPMySQL来说并不是特殊的,而是只要求你能够从你的服务器读取和输出JSON数据。

让我们开始吧 

首先我们必须设置表单的url, 这是一个能获得POST数据并将其写进我们的数据库的PHP脚本.

var form_employee = new Ext.form.Form({
               ...
               url:'forms-submit-process.php',
               ...
});

我们的数据包含5个字段:id, name, title, hire_dateactive,这些字段可以被取回并放置到一个数据存储对象(Store)中。

以下的程序构造了一个数据存储对象,在这个时候没有数据被取回,我们的数据代理(Proxy)对象提交到一个PHP脚本,用来取回数据库id14的行 并将它转换成一个JSON字符串。


employee_data = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({url: 'forms-submit-getdata.php?id=14'}),
reader: new Ext.data.JsonReader({},[ 'id', 'name', 'title', 'hire_date', 'active']),
remoteSort: false
});

接下来要做的是设定我们的事件监听者来监察什么时候数据被载入, 这个将保证我们不会在数据被载入之前填入表单。

employee_data.on('load', function() {
 
               // data loaded, do something with it here... 
 
});

当数据被载入后,我们可以取回数据并用setValue方法将其填入表单。这里我们用getAt(0) 从我们的数据存储对象里重新取回第一行数据(行zero)。


注意:这里使用的表单和表单字段在getting started tutorial中有定义和解释。

employee_name.setValue(employee_data.getAt(0).data.name);
employee_title.setValue(employee_data.getAt(0).data.title);
employee_hire_date.setValue(employee_data.getAt(0).data.hire_date);
employee_active.setValue(Ext.util.Format.boolean(employee_data.getAt(0).data.active));

我们将要创建提交按钮并添加到表单,记得给来源于表单字段的POST数据设定扩展参数。你将会发现通过行确定字段(id)对于让php脚本找到需要更新的行非常有用,同时为了更好的判断,还需要一个action判定。


我还使用isValid参数来保证表单在提交前符合每一个字段的要求。

form_employee.addButton('Save', function(){
               if (form_employee.isValid()) {
                              form_employee.submit({
                                             params:{
                                                            action:'submit',
                                                            id:employee_data.getAt(0).data.id
                                             }, 
                                             waitMsg:'Saving...'
                              });           
               }else{
                              Ext.MessageBox.alert('Errors', 'Please fix the errors noted.');
               }
}, form_employee);
 
form_employee.render('employee-form');

读取我们的数据

现在我们来读取数据

employee_data.load();

这样真的能够惊人简单的创建一个可用的表单,与成对的服务器段脚本接合,就能够将数据从数据库获取并写入修改后的数据。这些服务端脚本可以简单到只需几行而已。

 

EXT中的继承

Ext提供了这样的一个实用函数 Ext.extend (API 参考) 在EXT框架中实现类继承的机制。这赋予了你扩展任何JavaScript基类的能力,而无须对类自身进行代码的修改(这里通常指的是子类,或是从它继承的,一个基类)扩展Ext组件这是个较理想的方法。

要从一个现有的类创建出一个新类,首先要通过一个函数声明新类的构造器,然后调用新类属性所共享的扩展方法。这些共享的属性通常是方法,但是如果要在实例之间共享数据(例如,Java中的静态类变量),应该也一同声明。

JavsScript并没有提供一个自动的调用父类构造器的机制,所以你必须通过属性superclass在你的构造器中显式调用父类。第一个参数总是this,以保证构造器工作在调用函数的作用域。

MyNewClass = function(arg1, arg2, etc) {

   // 显式调用父类的构造函数

   MyNewClass.superclass.constructor.call(this, arg1, arg2, etc);

};

 

Ext.extend(MyNewClass, SomeBaseClass, {

 theDocument: Ext.get(document),

 myNewFn1: function() {

    // etc.

 },

 myNewFn2: function() {

   // etc.

 }

});

下面的一个例子是Ext的实际案例,用于可缩放,拖动元素,X、Y的坐标值指定了对象可在垂直、水平方向拖动的距离。

// 创建新类的构造函数

Ext.ResizableConstrained = function(el, config){

    Ext.ResizableConstrained.superclass.constructor.call(this, el, config);

};

 

// 扩展基类

Ext.extend(Ext.ResizableConstrained, Ext.Resizable, {

    setXConstraint : function(left, right){

        // 得到父类的属性ddsetXConstraint的引用

        this.dd.setXConstraint(left, right);

   },

 

   setYConstraint : function(up, down){

     // 得到父类的属性ddsetYConstraint的引用

     this.dd.setYConstraint(up, down);

   }

});

 

// 创建新类的实例

var myResizable = new Ext.ResizableConstrained('resize-el', {

   width: 200,

   height: 75,

   minWidth:100,

   minHeight:50,

   maxHeight:150,

   draggable:true

});

 

//调用新方法

myResizable.setYConstraint(0,300);

myResizable.setXConstraint(0,300);

按照直白语言,你可以把上面的代码理解成为:”Ext.ResizableConstrained 扩展了Ext.Resizable并实现了这些方法"。

posted on 2009-06-22 16:57  站在世界的屋顶  阅读(787)  评论(0)    收藏  举报