(73)封裝一個widget
醒目:必須在web環境下使用,無論是python的web.py或者是通過http訪問網站環境,都可以,但純本地是不可行的。
?
首先,什么是widget?
簡單來說,就是一個dom結點,比如像這樣:
<div>這是一個dom結點 </div>
?
為什么需要widget呢?
很簡單,比如,我們想在這樣一個地方:
<div class="nodes"></div>
?
添加很多個上面那個dom結點,比如像這樣。
<div class="nodes"><div>這是一個dom結點</div><div>這是一個dom結點</div> </div>
?
或者在很多地方添加這一個dom結點。
?
解決辦法①:
我們可以這么直接把他寫在HTML里;
?
優點:
①復制粘貼到所有需要他的地方,非常簡單
?
缺點:
①假如這個結點非常的復雜,可能還有一些事件(比如點擊后彈一個彈窗什么的),我們要ctrl + c、ctrl + v很多次;
②假如產品經理突然說,讓我們把這個改一下吧,因此我們可能需要在很多地方進行修改(但也有可能忘記把某個地方的改掉);
?
解決辦法②:
封裝一個widget
?
優點:
①上面的缺點都不是問題了;
?
缺點:
①假如這個結點很簡單(比如就上面一行),那么這么寫反而復雜了。
?
?
封裝方法:
①基礎是上面的類的繼承,我們需要繼承一個類,這個類就是widget的基礎類;
類:"dijit/_WidgetBase"
?
②其次,我們需要一個模板類,這個模板做什么用的呢,很簡單,是幫我們省去重復工作的,我們使用這個類,于是就可以省去重復寫創建dom結點的工作了,只需要修改模板內的東西即可。
?
③為了說的更簡單點,我給一個基礎類聲明,其創建方式是類的封裝(具體見之前的71);
代碼如下:
define(["dojo/_base/declare","dijit/_WidgetBase","dijit/_TemplatedMixin","dojo/text!template.html"], function (declare, _WidgetBase, _TemplatedMixin, template) {return declare('template', [_WidgetBase, _TemplatedMixin], {name: "這是一個模板的文件",? //替換模板內的${name}位置baseClass: "templateClass",? //模板的根div的css類templateString: template,?? //這個template就是模板的內容,通常這么寫就沒錯了postCreate: function () {?? //渲染模板,還有給他加事件就放在這一步了this.inherited(arguments); }}); });
?
define引入的第一個插件是聲明類;
第二個插件是widget;
第三個插件是模板類;
第四個是模板(指向一個html);
第五個是on,用于綁定觸發事件的
?
同樣,為了簡單說明,有以下前提:
新建的文件和dojo文件夾、dijit文件夾等在同一個根目錄下,包括:
《1》調用類的html文件;
《2》類的聲明的js文件;
《3》類的模板文件;
?
④首先創建一個test.html文件,這個html文件是調用類的html文件;
我們還需要創建一個類文件test.js,這個js文件聲明一個類;
我們最后創建一個模板文件template.html,這個文件作為模板;
?
⑤首先給出模板文件的html內容:
<div><div data-dojo-attach-point="node" class="node">${name}</div> </div>
?
其中:
data-dojo-attach-point:可以通過這個屬性找到該結點,可以理解為id一樣的東西,同一個模板文件內不能重復;
class就是其類,就像正常的div的class屬性一樣;
${name}:在js文件里,可以通過某個變量來控制他,可以理解為,那個變量的值就是${name}顯示的東西
?
⑥接下來給出js文件:
define(["dojo/_base/declare","dijit/_WidgetBase","dijit/_TemplatedMixin","dojo/text!template.html","dojo/on"], function (declare, _WidgetBase, _TemplatedMixin, template, on) {return declare('template', [_WidgetBase, _TemplatedMixin], {name: "這是一個模板的文件",? //替換模板內的${name}位置baseClass: "templateClass",? //模板的根div的css類templateString: template,?? //這個template就是模板的內容,通常這么寫就沒錯了postCreate: function () {?? //渲染模板,還有給他加事件就放在這一步了this.inherited(arguments);this.aEvent();},aEvent: function () {var self = this;on(this.node, "click", function () {self.node.innerHTML += "<br>——添加了一些內容";})}}); });
?
我簡單解釋一下這個js文件:
《1》aEvent是這個widget綁定的一個方法,凡是使用這個widget的地方,都會自動綁定這個事件。之所以能自動綁定,是通過postCreate這個方法調用的原因。
?
《2》postCreate是創建widget必然會被執行的函數,不需要我們手動調用,這個函數是通過遞歸被執行的(總之知道他肯定會被執行就是了);
他是創建widget被執行的一系列的函數之一,準確的說是倒數第二個,倒數第一個是startup,一般是被手動調用的;
?
《3》這個widget展現出來的作用是。掛載某一個html的dom結點之上,然后點擊文字部分的時候,會觸發一個事件,而這個事件的效果是增加一行文字,文字內容就是innerHTML里面添加的內容。這個事件可以被無限次觸發;
?
⑦最后給出test.html文件的內容:
<!DOCTYPE html> <html> <head><meta charset="utf-8"> </head> <script>var dojoConfig = {async: true}</script> <script src="dojo/dojo.js"></script> <script>require(["test"], function (test) {var te = new test({}, "base");}) </script> <style>.node {border: 1px solid #ccc;} </style> <body> <div id="base"></div> </body> </html>
?
我調用這個widget的方法很簡單,require一個test(實際是test.js那個文件),然后在回調函數傳參給他,然后new一個test(就是創建一個widget),但這個widget放在哪里呢?很簡單,test的第二個參數就是widget被放置的地方(因為id="base"是相符的)。
?
?
最后:
因為某些人可能沒法創建web環境,因此給一個示例地址:
http://www.jianwangsan.cn/test.html
ps:這是我的個人網站,理論上來說,應該是沒有毒的吧。。。。