« Linux下Apache+cgi的配置方法(虚拟机环境)微软Windows Live Spaces出现域名解析错误 »

prado框架新控件的生成方法

在使用prado的过程中,为了生成更加复杂和友好的界面,就需要我们编写新的控件的。
 
总的来说,有两种生成新控件的方式:组合已经存在的控件和扩展已经存在的控件。这两种生成控件的方式都需要它们的类继承自TControl类或者它的子类
 
下面对这两种方式进行介绍:
 
一、组合已经存在的控件
组合是生成新控件最简单的方式,我们只需要专注于已经存在的控件,有两种通过组合生成新控件的方式,一种是扩展TCompositeControl类,覆盖TControl::createChildControls()这个方法;另一种是扩展TTemplateControl类或者它的子类,编写一个control template.,相对而言,后者要简单一点,并且通过这种方式可以很容易的了解界面的布局,但是前者的效率要比后者高,因为它不需要解析模板。
 
在界面的实际开发过程中,我们可能经常需要将一个labele控件和一个textbox控件组合使用,如果能将这两个空间组合起来生成一个新的控件,那是不是会使我们的开发容易很多呢?下面的例子是通过上述两种方式生成一个新控件LabeledTextBox的过程:
 
1、通过编写控件模板的方式组合出新控件
 
这种方式需要两个文件:控件类LabeledTextBox.php和控件模板文件LabeledTextBox.tpl,这两个文件必须要放在同一个目录。
 
与编写prado page文件差不多,下面是控件模板LabeledTextBox.tpl的代码:
<com:TLabel ID="Label" ForControl="TextBox"/>
<com:TTextBox ID="TextBox"/>
它声明了一个id为Label的TLabel控件和一个idTextBoxTTextBox控件,我们需要注册这两个控件。我们可以通过在LabeledTextBox类文件里为这两个控件分别定义属性,例如,我们定义一个Label属性:
class LabeledTextBox extends TTemplateControl {
    public function getLabel() {
        $this->ensureChildControls();
        return $this->getRegisteredObject('Label');
    }
}
 
在上面的代码中,ensureChildControls()这个调用保证了Label属性被访问时成功创建label 和textbox这两个控件,TextBox属性也是如此。
 
在使用该方法组合新控件时,在page的Php文件中需要包含该新控件的路径,例如:example.php(LabeledTextBox控件放置在pages/ NewControls路径下)
<?php
 
Prado::using('Application.pages.NewControls.LabeledTextBox');
 
class Home extends TPage
{
    public function buttonClicked($sender,$param)
    {
       $sender->Text=$this->Input->TextBox->Text;
    }
}
 
?>
 
 
2、通过覆盖createChildControls()的方式组合新的控件
 
在组合新控件的过程中,最好的办法就是通过扩展TCompositeControl类来覆盖createChildControls()方法,因为它不需要模板,因此可以节省解析模板的时间,从而提高效率。
 
下面是完整的通过扩展TCompositeControl类的事例代码:
class LabeledTextBox extends TCompositeControl {
    private $_label;
    private $_textbox;
    protected function createChildControls() {
        $this->_label=new TLabel;
        $this->_label->setID('Label');
        // add the label as a child of LabeledTextBox
        $this->getControls()->add($this->_label);
        $this->_textbox=new TTextBox;
        $this->_textbox->setID('TextBox');
        $this->_label->setForControl('TextBox');
        // add the textbox as a child of LabeledTextBox
        $this->getControls()->add($this->_textbox);
    }
    public function getLabel() {
        $this->ensureChildControls();
        return $this->_label;
    }
    public function getTextBox() {
        $this->ensureChildControls();
        return $this->_textbox;
    }
}
 
新的控件已经生成了,我们该如何使用呢?
<com:LabeledTextBox ID="Input" Label.Text="Username"/>
跟使用普通的prado控件一样,是不是很简单?Label.Text就是lable的文字描述。
 
 
二、扩展已经存在的控件
 
扩展已经存在的控件跟传统的类继承方式一样,通过这种方法我们可以通过覆盖它们的属性、方法、事件处理等定制一些已经存在的控件类。
这种方式的难度在于被覆盖的控件类的规模,举例来说,在定制TLabel控件中,我们需要使lable默认的颜色是红色,这仅仅需要我们在构造函数里设置ForeColor属性就ok了。比较难的是创建一个具有新功能的控件,通常,这种方式的控件类需要继承低层次的基础类,如TControl 或者TWebControl类。
 
1、扩展TControl类
TControl 是所有控件类的基础类.有两个最重要的方法:
·         addParsedObject() –这个方法在标识一个模板里所有的组件或者有tag标签的文本时被调用到。默认的,这些组件或者文本要被添加到控件的容器里,新生成的控件在处理它自身的内容时可能要覆盖这个方法,例如,TListControl只会接受TListItem组件,这些组件要被添加到TListControl的容器中。
·         render() – 这个方法就是绘制界面,默认的,它将某一控件的所有内容都呈现出来,新生成的控件类可以覆盖这个方法定制具有特色的类.
 
其它的一些重要属性和方法:
·         ID – 标识一个控件的字符串,如果没有定义,它会自动生成.
·         UnqiueID – 跟上面的意思差不多,可以通过调用TControl::findControl()来定位一个控件。
·         ClientID – 类似UniqueID, 在界面的HTML元素里可以体现出来。.
·         Enabled –设置某控件当前是否enable,子控件继承父控件的该属性。
·         Parent –该控件的父控件.它将负责该控件是否进行绘制和决定该控件的绘制结果是否进行存放。
·         Page – 包含控件的页面.
·         Controls –所有子控件的容器,包括静态的文本,它可以是数组,并且实现了Traversable 接口,将一个子控件添加到该控件中,简单的将它插入到合适的位置就可以了。
·         getViewState() and setViewState() – 这两个方法通常用来定义控件的属性,它们通过设置viewstate 属性的方法.
·         saveState() and loadState() – 这两个方法提供现场和保存现场,可以被覆盖.
 
2、扩展 TWebControl
TWebControl作为一个主要的基础类在呈现HTML元素时被用到,它提供了设置HTML元素属性的方法,它分解了 TControl::render()为如下的更能描绘HTML元素的方法:
·         addAttributesToRender() – 添加一个要被描绘的HTML元素的属性,当需要描绘不同的属性时,该方法经常要被覆盖掉。
·         renderBeginTag() – 描绘HTML元素的开始标签
·         renderContents() – 类似上面的.当需要定制内容时该方法要被覆盖掉。
·         renderEndTag() -描绘HTML元素的结束标签
当描绘HTML的tag时,TWebControl类实现了getTagName()去获取该标签的名字,如TButton类中调用该方法返回的就是“input”。可以通过覆盖该方法来描绘不同的标签名称。
 
3、创建具有特殊功能的控件
    如果一个控件需要在客户端接收事件然后传递给服务器端,例如TButton,需要实现IPostBackEventHandler这个接口。
 
如果一个控件能够加载数据,例如TTextBox,需要实现IPostBackDataHandler这个接口。
 
总结:纵观prado的所有控件,其实现原理就是通过使用继承TControl类或者TWebControl中对HTML标准控件进行了一次包装的接口,这些接口主要通过组织、描绘HTML标签,最终呈现在界面上,prado在搜集所有的HTML元素的属性时是通过setviewstate和getviewstate来实现。控件中的事件处理,和用户输入合法性的检查,是通过注册事件处理的handler和validator来实现。在每个application运行时,会将事件处理程序和validator的判断程序放在js文件中,客户端直接包含进来,所以有些简单的事件处理和错误检查是在客户端进行的。
 
  
原创文章如转载,请注明:转载自悠悠博客 [ http://www.ajaxstu.com/ ]

相关文章:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。