博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dojo Widget系统(转)
阅读量:5014 次
发布时间:2019-06-12

本文共 5864 字,大约阅读时间需要 19 分钟。

Dojo 里所有的小部件(Widget)都会直接或间接的继承 dijit._Widget / dijit._WidgetBasedijit._Widget 是 dojo 1.6 和 1.6之前的版本的基类, 在 dojo 1.7 之后的版本, 官方建议直接继承 dijit._WidgetBase 类(继承 dijit._Widget 也可以, dijit._Widget 继承了 dijit._WidgetBase).Dojo 里丰富多彩的 Widgets 都是以这个类为基础, 那么这个类到底内藏了什么玄机呢? ...查看 dijit._WidgetBase (dojo 1.6) 的类定义:{    // widget 的 id, 唯一的, 如果用户指定了 id 并且是不重复的用    //     使用, 否则将忽略, 系统生成一个.    id: "",        // widget 的语言, 很少用    lang: "",        // 方向, "ltr" or "rtl"    dir: "",        // 最终生成的 widget 根结点上的 css class name    "class": "",        // 最终生成的 widget 根结点上的 inline css style,    //    类型可以是: 一个字符串, 或 Object {width: '80px'}    style: "",        // 作用1: 相当于标准的 HTML title 属性, mouse hover 的时候有个tooltip    // 作用2: 当这个 widget 是 TabContainer, AccordionContainer 的子 widget    //        的时候, 就对应特定 widget 的 title, 比如 tab name.    title: "",        // 和上面的 title 属性合作, 当 title 被当成 tab name, ... 时, tooltip    //    属性指的就是标准的 HTML title 属性    tooltip: "",        // widget 根节点上的 class, 用来创建指示 widget 状态(State)的 css classes    baseClass: "",        // 引用原始的 DOM 节点(widget 要被创建在这个节点上)    srcNodeRef: null,        // 引用 widget 在页面上生成后的 DOM Node    domNode: null,        // 当 widget(比如 ContentPane) 接受 innerHTML / 子widget 的时候, 一定要定义这个属性,     //    它指示 innerHTML / 子 widget 插入到哪个节点里    containerNode: null,        // 把 widget 的属性和其 DOM 节点绑定    attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""},        // Path to a 1x1 image, 占位, widget icon图片会被真正 css background image 取代    //    方便运用 css sprit 技术    _blankGif: (dojo.config.blankGif ||         dojo.moduleUrl("dojo", "resources/blank.gif")).toString()}============================Widget 的生命周期:constructorpostscript|---create    |---postMixInProperties ( 刚刚读入了用户定义的属性 )    |---buildRendering  ( 创建 widget.domNode )    |---postCreate ( 此函数被触发时, widget.domNode已经被创建好了, 但是**并不一定**已经被连接到页面的 DOM 结构中                              所以, 此函数内最好不要执行 place 定位, 以及计算dom node 占页面尺寸等相关操作)startup ** 很多讲 Widget 系统的文章都斩钉截铁地说, postCreate() 是在 dom fragment创建好了, 但是还没有连到页面DOM树中去的时候触发, 看了源码, 又做了测试后发现这是不对的. 此时有可能已经连到DOM树中, 也可能没有.**============================ Widget.postscripte postscript: function(params, srcNodeRef) {    this.create(params, srcNodeRef);}开始. 参数 params 是 Object 初始化 widget 的属性, srcNodeRef 为 Dom node / String这个函数只是调用了 create 函数, 由 create 完成具体的 初始化 操作.=============================Widget.createfunction create(/*Object?*/params, /*DomNode|String?*/srcNodeRef) {    // 保存在页面上的, 之后要被转换为 Widget 的节点    this.srcNodeRef = dojo.byId(srcNodeRef);    // 保存所有 dojo.connect() 返回的句柄, 用于垃圾回收, 阻止内存溢出    this._connects = [];    // 保存所有 dojo.subscribe() 返回的句柄, 用于垃圾回收, 阻止内存溢出    this._subscribes = [];    // mix in our passed parameters    if(this.srcNodeRef && ( typeof this.srcNodeRef.id == "string")) {        // 页面上的 Dom node 的 id, 做为 widget 的 id        this.id = this.srcNodeRef.id;    }    if(params) {        // 添加用户自定义的属性和方法        this.params = params;        dojo._mixin(this, params);    }    // 当 mixin 完成后, 调用 postMixInProperties()    this.postMixInProperties();        // 如果, 此时仍没有 id 属性, 系统自动生成一个 id    if(!this.id) {        // Example: dijit_Tooltip_1        this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g, "_"));    }    // 将当前 widget 加入到 dijit.registry 列表中    dijit.registry.add(this);        // 确定有了 id 后, 调用 buildRendering()    this.buildRendering();    if(this.domNode) {        // 将 attributeMap 中的所有属性 copy 到新建 widget 的 Dom node 上        this._applyAttributes();        // 用真正的 widget's dom node 替换页面中占位的 dom node        var source = this.srcNodeRef;        if(source && source.parentNode && this.domNode !== source) {            source.parentNode.replaceChild(this.domNode, source);        }    }    if(this.domNode) {        // 为 dom node 添加 widgetId 属性        this.domNode.setAttribute("widgetId", this.id);    }    // ** 很重要的方法 postCreate()    this.postCreate();    // 如果 srcNodeRef 已经被真正的 widget dom node 替换了, 就删除它, 方便    // GC回收资源    if(this.srcNodeRef && !this.srcNodeRef.parentNode) {        delete this.srcNodeRef;    }    // 设置标记    this._created = true;}============================= Widget.postMixInpropertiespostMixInProperties: function() {    // 此时已经读入了用户初始化 widget 的属性,    // 但是, widget template 还没有始初化, 在这函数里可以设置    // template 里的相应属性}=============================Widget.buildRenderingbuildRendering: function() {    // 设置 widget 的 domNode 属性, 添加相应 css classes        if(!this.domNode) {        this.domNode = this.srcNodeRef || dojo.create('div');    }    // 如果页面 UI 为 rtl style, 则在所有 css class 加 Rtl 后缀    if(this.baseClass) {        var classes = this.baseClass.split(" ");        if(!this.isLeftToRight()) {            classes = classes.concat(dojo.map(classes, function(name) {                return name + "Rtl";            }));        }        dojo.addClass(this.domNode, classes);    }}=============================widget.postCreate此时, 代表新建的 widget 的 dom node 已经完全创建好了, 但是并不一定已经被连入了主页面的 dom tree.我们可以在这个函数里面做最多的自定义操作, 实际上, 我们自己写 widget 的时候, 大多数的操作也在这个函数里面进行=============================widget.startup当这个函数触发的时候, widget's dom node 已经连到了页面上的DOM中, 相关联的 widgets 也完成了 create() 周期.当自定义的 widget 有子 widgets 的时候, 这个方法就非常有用.对于 layout widget 这个方法也很有用.startup: function() {    this._started = true;}widget destroy 的通用函数是 widget.destroyRecursive()destroyRecursive: function(/*Boolean?*/ preserveDom) {    this._beingDestroyed = true;    this.destroyDescendants(preserveDom);    this.destroy(preserveDom);}this.destroyDescendants(preserveDom)作用: 如果这个 widget 有子 widget, 会遍历所有 子widget, 并在其上面递归调用 destroyRecursive() .this.destroy(preserveDom)这个函数主要进行了清理工作, 内部处理过程按顺序如下 :1) 调用 uninitialize(). 这个函数在基类中是空函数, 专门留组用户去覆盖, 做一些自定义的析构操作2) 清除所有 dojo.connect + dojo.subscribe 的句柄3) 销毁做为模版的一部分而创建的 widget4) 调用 dwstroyRendering(preserveDom), 这个函数会根据参数 preserveDom 为 true / false 去选择, 只是删除 domNode 上的 widgetId 属性, 或是直接把 domNode destroy掉

来自:

转载于:https://www.cnblogs.com/zuiyirenjian/p/3380598.html

你可能感兴趣的文章
Excel2007制作直方图和正态分布曲线图
查看>>
android adb常用指令
查看>>
Android框架之路——GreenDao3.2.2的使用
查看>>
类方法WCF学习笔记-KnowTypeAttribute用法
查看>>
平台程序微信平台开发应用的签名
查看>>
程序卡OK6410裸板更新程序_update
查看>>
MYSQL用户名:root
查看>>
JavaScript 开发规范要求
查看>>
Devstack 安装OpenStack Pike版本(单机环境)
查看>>
Javascript 函数初探
查看>>
类的定义、声明使用
查看>>
转载,gini系数代码对应的公式
查看>>
编译安装mysql-5.6.40
查看>>
年终总结
查看>>
初创互联网公司技术架构变迁之路
查看>>
【BZOJ 3676】 3676: [Apio2014]回文串 (SAM+Manacher+倍增)
查看>>
【网络流24题】No. 13 星际转移问题 (网络判定 最大流)
查看>>
解析$.grep()源码及透过$.grep()看(两次取反)!!的作用
查看>>
[模板] 字符串hash
查看>>
SGU438_The Glorious Karlutka River =)
查看>>