2006年10月27日星期五

Microsoft Ajax Beta1 - 边学边用边补充 (Part 2 - DragDropList)

由于我在做一个类似Live.com的东西,所以需要类似WebPart的功能。我不清楚Atlas扩展的那个所谓的Cross Browser WebPart到底是什么,支持如何,所以不敢去尝试,从而决定用DragDropList。

首先,关于如何使用DragDropList,可以参考Dflying的以下两篇文章:

参照第二篇文章轻松制作出WebPark拖放效果来是完全没问题,接下来要做的就是让用户拖放修改后的界面保存下来。这时候ASP.NET 2.0新增的Profile Service就是一个很好的选择,而且Atlas也包括对Profile读写的支持。接着问题就来了,何时能够获取到拖放结束的事件然后更新Profile呢?DragDropList和DraggableListItem没有对外公开任何事件,所以在使用它们快速实现类似WebPart的功能时仅仅能够获得视觉上的效果,无法对它们编程以实现任何有实际意义的东西。

这时候我选择了继承DragDropList来增加对外的事件触发能力,需要做的仅仅是重写onDragEnd方法。感谢Beta1的prototype书写方式,所有函数都是virtual的,这给重写带来了方便,不需要再用registerBaseMethod覆盖掉基类的函数。重写如下:
function MyDragDropList$onDragEnd(cancelled)
{
  debug.trace(cancelled);
  MyDragDropList.callBaseMethod(this, "onDragEnd", [cancelled]);
  this._dragVisual.style.width = null;
  this._dragVisual.style.height = null;
  this._dragVisual.style.zIndex = null;
}

debug.trace(cancelled)在这里是做演示作用,真正放在此位置的应该是一条触发事件的指令,甚至可以根据cancelled值决定是否触发,因为若它为true则实际上拖放没造成任何变化。

后面对样式属性的删除又是什么呢?这是对DragDropList某一个bug的work around。在拖动过程中,由于拖动的DomElement(也就是this._dragVisual)脱离了它原本的上下文,如果它原本的样式属性是width:100%那就会出问题,所以DragDropList取了它的offsetWidth属性来作为它的width,这样width的单位就一定是px。然而这却造成了另外一个问题,拖动后DomElement的width变成了一个单位为px的值,用户缩放浏览器时它就不能跟随缩放,这不符合我在CSS文件中定义width的单位为%时所期望的。于是我就在拖放结束后删除DragDropList对此DomElement样式的影响,让CSS文件定义的样式重新成为当前样式。

最后,提供一篇我觉得比较有价值的文章,方便大家实现自己的IDragSource和IDropTarget:Drag and Drop with Atlas: interfaces。文章中详细解释了这两个接口的各个方法,比起你自己去研究DragDropList的代码要简单一些。

没有评论:

发表评论