当前位置: 首页 > news >正文

动态载入数据的无刷新TreeView控件(8)

作为一个TreeView控件,显示、操作、动态加载都完成了,接下来最重要的就是怎么和用户代码结合了。事件是一种控件结合用户交互较好的方式,接下来就介绍一下在这个TreeView控件中的事件处理模型及实现。

    我们应该承认,C#的+=和-=方式的事件attach和dettach方式是非常清晰易用的。不过由于JavaScript不支持运算符重载,要实现这样的调用方式非常的困难,因为只有基本的JavaScript数值类型(int, float)才支持+=和-=操作。所以我们考虑按dom那样使用attachEvent的调用方式来实现TreeView控件的事件支持。

    Dom提供的attachEvent和dettachEvent其本质是对一个集合的操作,集合中可以存放一个事件的多个处理器引用。比如:
None.gif document.attachEvent('onload', handler1);
None.gif document.attachEvent('onload', handler2);
None.gif  //  . . .
None.gif 
document.attachEvent('onload', handlerN);

    于是我们先实现一个EventHander类,它就是用来存放事件处理器,并处理事件触发的。代码如下:
ContractedBlock.gif < script  language ="javascript" > dot.gif </ script >
    其实就是个集合,用来放置handlers,并同时触发。

    同时为了调用方便,为Object对象attach了一个AttachEvent的原型方法:
None.gifObject.prototype.AttachEvent =  function(eventName, eventHandler)
None.gif{
None.gif     if (  typeof(eventName) != 'string' ||  typeof(eventHandler) != ' function' )
None.gif    {
None.gif         return  new Error('eventName, eventHandler. Error parameters type.');
None.gif    }
None.gif     if ( eventName[0] != 'e' || eventName[1] != '_' )
None.gif    {
None.gif        eventName = 'e_' + eventName;
None.gif    }
None.gif     var evt =  this[eventName];
None.gif     if (  typeof(evt) != 'undefined' )
None.gif    {
None.gif         if ( __typeof__(evt) == 'EventHandler' )
None.gif        {
None.gif            evt.AttachHandler(eventHandler);
None.gif        }
None.gif         else
None.gif        {
None.gif             this[eventName] =  new EventHandler( this, eventName, eventHandler);
None.gif        }
None.gif    }
None.gif};

    定义好了事件的处理模型,我们在TreeView中怎么使用呢?下面一Collapse操作为例,如果我们要再TreeNode执行了Collapse后做一些用户自定义的事情,比如修改图标什么的。于是我们在TreeNode中定一个事件,名叫:e_Collapsed。修改Collpase方法如下:
None.gifTreeNode.prototype.Collapse =  function()
None.gif{
None.gif     var elmtNode =  this.m_Element;
None.gif     var childTree = elmtNode.nextSibling;
None.gif     if ( childTree )
None.gif    {
None.gif        childTree.style.display = 'none';
None.gif         this.m_IsChildExpanded =  false;
None.gif        elmtNode.OpIcon.src = TreeStyle.OpIcon( this.GetOpIconName());
None.gif         if (  this.e_Collapsed )
None.gif        {
None.gif             this.e_Collapsed.Execute('collapse');
None.gif        }
None.gif    }     
None.gif};

    其实就是添加了一个触发eventHandlers的调用 this.e_Collapsed.Execute('collapse');。使用这个event和使用DHMTL的dom中的attachEvent一样,并且也支持attach多个eventHandler到一个事件上。
None.gif  var node =  new TreeNode('TestNode');
None.gif node.AttachEvent('Collapsed', fnCollapsed);
    // 这里把事件名写成'Collapsed'和'e_Collapsed'是完全一样的,AttachEvent内部做了处理。

    eventHandler就是一个普通的函数,只是它的arguments[0]和arguments[1]是sender和eventArgs。上面示例的处理函数示例为:
None.gif  function fnCollapsed(sender, e)
None.gif {
None.gif      var node = sender;
None.gif     node.SetCustomizeIcon('E:\\Working\\Private\\TreeView\\Images\\close.gif');
None.gif     status = 'collapsed status: ' + e + ', ' + sender.m_Id;
None.gif }
    作用是把当前TreeNode的图标换为'close.gif'。

    使用上面的方法,我们可以为TreeNode实现以下常用的事件:
None.gif  this.e_Clicked =  null;
None.gif  this.e_SelectedChanged =  null;
None.gif  this.e_CheckedChanged =  null;
None.gif  this.e_NodeCreating =  null;
None.gif  this.e_Expanded =  null;
None.gif  this.e_Collapsed =  null;
None.gif  this.e_Appended =  null;

    这些事件在没有AttachEvent之前不会产生任何的处理代价,除了一个if判断。

    to be continued ...


本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。

相关文章:

  • ubuntu-基本命令篇-13-用户管理
  • 四大中三家已面向客户推出机器人业务解决方案?别逗了,先用机器人自我革命吧! post by 上海嘉冰信息技术...
  • python基础实践(二)
  • [Spring Cloud Task]3 框架配置详解
  • node.js
  • 本周末预计更新博客内容
  • 微信开发https服务搭建
  • wii 入门之路--fatt
  • 冒泡排序的多种写法、逻辑
  • 获取 Android 版本
  • 3.7 su命令 3.8 sudo命令 3.9 限制root远程登录
  • 当微信小程序遇上filter~
  • webpack 简单使用
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • wireshark使用教程
  • 网络传输文件的问题
  • [iOS]Core Data浅析一 -- 启用Core Data
  • [数据结构]链表的实现在PHP中
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • create-react-app做的留言板
  • HomeBrew常规使用教程
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • Node 版本管理
  • npx命令介绍
  • PAT A1120
  • ReactNative开发常用的三方模块
  • Vim 折腾记
  • Vue学习第二天
  • 从PHP迁移至Golang - 基础篇
  • 当SetTimeout遇到了字符串
  • 多线程 start 和 run 方法到底有什么区别?
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 马上搞懂 GeoJSON
  • 前端技术周刊 2019-01-14:客户端存储
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 微信小程序--------语音识别(前端自己也能玩)
  • 小程序button引导用户授权
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ​马来语翻译中文去哪比较好?
  • (1)(1.9) MSP (version 4.2)
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (zhuan) 一些RL的文献(及笔记)
  • (一)kafka实战——kafka源码编译启动
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .jks文件(JAVA KeyStore)
  • .NET Core 项目指定SDK版本
  • .Net Core 中间件验签
  • .net FrameWork简介,数组,枚举
  • .NET Micro Framework 4.2 beta 源码探析
  • .net 发送邮件
  • .net 托管代码与非托管代码
  • .net(C#)中String.Format如何使用
  • .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?