Ext JS - Learning Center

Tutorial:创建一个可复用的AJAX对话框--一个完成好的例子

From Learn About the Ext JavaScript Library

Jump to: navigation, search
Summary: 创建一个可复用的AJAX对话框--一个完成好的例子
Author: Jack Slocum (译者:Frank Cheung)
Published: 2007-2-3 14:07:45
Ext Version: yui-ext 0.33
Languages: cn.png Chinese

Contents

案例介绍

随同官方0.33的发布,在礼拜二我贴出了一个新的Image Chooser的范例。本文中,我们将会深入了解chooser的重要代码,希望你能更好地理解如何将多个组件组合成新组件,一个适合你自身程序的组件。

先看看它的界面:

2007110518164603.gif

观看例子

它是怎么运作的?

下列代码只是显示一个对话框。这个例子我是收集好图片然后插入到一个页面。你也可以填到form字段中,或插入到你喜欢的Rich-text editor,或是其它怎样,任君选择。

var choose = function(btn){
    if(!chooser){
        chooser = new ImageChooser({
            url:'get-images.php',
            width:515, 
            height:400
        });
    }
    chooser.show(btn.getEl(), insertImage);
};
 
btn = new YAHOO.ext.Button('buttons', {
    text: "Insert Image",
    handler: choose
});

后台是一个读取某个目录下图片的PHP文件,返回一个包含可用图片信息的JSON 。

“as your type”是由JSONVIEW类提供的一个客户端缩略图的排序、分类。稍后我们会继续讨论,先看看dialog。

创建对话框

我选择了一个有 BorderLayout的BasicDialog。尽管BorderLayout用在这里有点大材小用,但这能够有机会示范一下LayoutDialog类。

Dialog可以通过autoCreate的选项,允许不存在标记(xhtml makeup)的情况下,被创建起来。

var dlg = new YAHOO.ext.LayoutDialog(config.id || YAHOO.util.Dom.generateId(), {
    autoCreate: true,
    minWidth: 400,
    minHeight: 300,
    syncHeightBeforeShow: true,
    shadow: true,
    fixedcenter: true,
    center: {
        autoScroll: false
    },
    east: {
        split: true,
        initialSize: 150,
        minSize: 150,
        maxSize: 250
    }
});
dlg.setTitle('Choose an Image');
dlg.getEl().addClass('ychooser-dlg');

按钮

注意setDefaultButton()的调用。这强迫默认的按钮在dialong中出现。为使一些快捷键能用起来,这个dialog必须带焦点。当dialog显示时,,默认的方式定义的按钮就带有焦点,因此,不需要特别设置焦点,ESC键就能工作起来。ok按钮是禁止的,因为如果用户没选好图片,是不能够插入图片的。

dlg.setDefaultButton(dlg.addButton('Cancel', dlg.hide, dlg));
this.ok = dlg.addButton('OK', this.doCallback, this);
this.ok.disable();

加入Toolbar

首先我们创建一个YAHOO.ext.Toolbar的实例,渲染为dialog body元素中的一个div。

然后我们动态创建一些Toolbar的控制项,并绑定一些事件。

this.sortSelect = this.dlg.body.createChild({
    tag:'select', children: [
        {tag: 'option', value:'name', selected: 'true', html:'Name'},
        {tag: 'option', value:'size', html:'File Size'},
        {tag: 'option', value:'lastmod', html:'Last Modified'}
    ]
});
this.sortSelect.on('change', this.sortImages, this, true);
 
this.txtFilter = this.dlg.body.createChild({
    tag:'input', type:'text', size:'12'
});

bufferedListener()是属于0.33版Observable和Element的新东东。它绑定一个事件,通过一定的延迟,缓冲多个触发。这里我们设置500毫秒。也就是说当用户输入时,过了半秒才触发事件。

this.txtFilter.bufferedListener('keyup', this.filter, this, 500);

接着加入东西到Toolbar,和加点用户提示文本。

this.tb.add('Filter:', this.txtFilter.dom, 'separator', 'Sort By:', this.sortSelect.dom);

初始化布局

正如我开始所述,一个布局是很简单。首先我们为主区域增加一个主ContentPanel,然后传入toolbar以便让panel/layout 知道那里可以调整大小。使用beginUpdate()和endUpdate(),让layout准备进行一系列的更新,并增加内容的同时保持 layout相互之间的计算。

var layout = dlg.getLayout();
layout.beginUpdate();
var vp = layout.add('center', new YAHOO.ext.ContentPanel(YAHOO.util.Dom.generateId(), {
    autoCreate : true,
    toolbar: this.tb,
    fitToFrame:true
}));
var dp = layout.add('east', new YAHOO.ext.ContentPanel(YAHOO.util.Dom.generateId(), {
    autoCreate : true,
    fitToFrame:true
}));
layout.endUpdate();

创建DomHelper.Templates

这里的模版用于渲染服务器返回的JSON数据。“thumbTemplate”用于渲染由JsonView提供的缩略图;“detailsTemplate”用于渲染你单击后显示详细的内容。两者都经过编译达到最高性能。

this.thumbTemplate = new YAHOO.ext.Template(
	  '<div class="thumb-wrap" id="{name}">' +
	  '<div class="thumb"><img src="{url}" title="{name}"></div>' +
	  '<span>{shortName}</span></div>'
  );
  this.thumbTemplate.compile(); 
this.detailsTemplate = new YAHOO.ext.Template(
	  '<div class="details"><img src="{url}"><div class="details-info">' +
	  '<b>Image Name:</b>' +
	  '<span>{name}</span>' +
	  '<b>Size:</b>' +
	  '<span>{sizeString}</span>' +
	  '<b>Last Modified:</b>' +
	  '<span>{dateString}</span></div></div>'
  );
this.detailsTemplate.compile();

创建YAHOO.ext.JsonView

我反复唠叨着这个类有多cool,终于有机会在这里大展身手了。

首先,我们创建JsonView实例,传入一个模版给它。选项“singleSelect:true”告知层我们想激活选区并且是某一时间内只激活一个。

this.view = new YAHOO.ext.JsonView(viewBody, this.thumbTemplate, {
	singleSelect: true,
	jsonRoot: 'images',
	emptyText : 'No images match the specified filter'
   });

接着我们加入事件处理器(event handler)。留意我们又使用bufferedListener(),默认250毫秒的缓冲

this.view.bufferedListener('selectionchange', this.showDetails, this);
this.view.on('dblclick', this.doCallback, this, true);
this.view.on('loadexception', this.onLoadException, this, true);

如果没有匹配的结果,就指定一个取消选区的文本。

this.view.on('beforeselect', function(view){
    return view.getCount() > 0; // returning false cancels the selection
});

执行prepareDate()来自定义渲染每个JSON结果

this.view.prepareData = function(data){
    data.shortName = data.name.ellipse(15);
    data.sizeString = formatSize(data.size);
    data.dateString = new Date(data.lastmod).format("m/d/Y g:i a");
    lookup[data.name] = data;
    return data;
};

要在客户端排序和分类Json数据,很是简单!

您只要精通键入这短短三行的代码,便可完成分类(filter)。附加bufferdListener()事件到txtFilter字段然后输入这两行语句。JsonView会自动处理filters之间的排序和创建一个快照snapshot来使得filter更干净。

var filter = this.txtFilter.dom.value;
this.view.filter('name', filter);

排序也不难

var p = this.sortSelect.dom.value;
this.view.sort(p, p != 'name' ? 'desc' : 'asc');

更多高级应用,请参与jsonview类的文档

接下来呢?

这个dialog可以干更多的事情。例如在左边放颗树,又或者用于上传文件。有空的话,我会增加此类功能如果你觉得这是有益的事情。

原文地址:http://www.jackslocum.com/blog/2006/12/17/how-to-create-a-reusable-ajax-driven-web-dialog-a-working-example/

  • This page was last modified on 20 August 2008, at 07:06.
  • This page has been accessed 5,667 times.