溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

一步一步使用Ext JS MVC與Asp.Net MVC 3開發(fā)簡單的CMS后臺管理系統(tǒng)之登錄窗口

發(fā)布時間:2020-06-25 10:01:26 來源:網(wǎng)絡(luò) 閱讀:2121 作者:tianxiaode2008 欄目:編程語言

完成配置后,要做的是完成登錄頁面。因為要實現(xiàn)登錄之后寫入認(rèn)證信息到Cookie,因而必須做一次跳轉(zhuǎn)。當(dāng)然,不做跳轉(zhuǎn),或不寫入認(rèn)證信息也行,但問題比較復(fù)雜,在這里還是做簡單處理比較合適。還有就是寫入認(rèn)證信息的目的是為了在控制器通過特性控制方法的權(quán)限。

      既然要跳轉(zhuǎn)一次,就有兩種思路了,一種是為了快速顯示登錄頁,可不加載Ext JS,而是使用傳統(tǒng)的頁面,顯示一個登錄頁,這樣頁面加載快,用戶感受也好很多。第二種方式就是用Ext JS窗口做一個登錄窗口,不過要加載Ext JS庫,顯示時間會久點,體驗不是太好。不過加載過Ext JS,后面顯示主框架頁的時候就可以利用緩存數(shù)據(jù)。采用那種方式,根據(jù)自己喜好或項目要求定吧。本文是演示Ext JS的,因而會采用第二種方式,寫一個登錄窗口。

      登錄窗口作為常用組件,在其它項目也會用到,因而很適合寫成一個擴展。這里還要考慮一個問題,是寫成單例模式的擴展,還是單純是擴展?單例模式的好處是在 頁面中直接用show方法顯示就行了,而純擴展的好處的是可以通過配置項自定義標(biāo)題、圖標(biāo)這類的東西。筆者更喜歡單例模式,原因是直接在擴展中修改標(biāo)題之 類的這些東西,比使用配置項來定義來得方便,畢竟是Javascript寫的擴展,修改起來比使用C#這些語言的擴展容易得多了。

      目標(biāo)明確后,就可以動手了,在解決方案資源管理器中選擇Scripts\ExtJS\ux目錄,單擊右鍵選擇添加,新建項,在彈出窗口中如圖6那樣選擇 Jscript文件,并將名稱修改為login.js(以后的項目的可直接將該文件復(fù)制到該目錄),單擊添加按鈕創(chuàng)建文件。這里要注意,文件名不能用類的 全名做文件名,因為動態(tài)加載會根據(jù)類名自動找到目錄并加載文件,類名中最后一個小數(shù)點后的名稱就是文件名,例如,登錄窗口的類全稱為 Ext.ux.Login,而login就是文件名。

一步一步使用Ext JS MVC與Asp.Net MVC 3開發(fā)簡單的CMS后臺管理系統(tǒng)之登錄窗口

 

      如果想要在腳本中使用ExtJS的提示信息,可將書附帶的資源包中的Ext.js文件復(fù)制到ExtJS目錄中,復(fù)制后,在解決方案資源管理器將Ext.js拖到到login.js文件中,就會生成以下代碼:

[javascript] view plaincopy
  1. /// <reference path="../Ext.js" />  


      這樣,就可以在腳本中使用Ext  JS的提示信息,在文件中輸入“Ext.cr”,將看到如圖7所示的效果。

一步一步使用Ext JS MVC與Asp.Net MVC 3開發(fā)簡單的CMS后臺管理系統(tǒng)之登錄窗口

 

      現(xiàn)在,先把類的定義寫好,包括父類、單例模式、窗口標(biāo)題、寬度和高度。窗口的標(biāo)題為“簡單的CMS后臺管理系統(tǒng)后臺登錄窗口”。寬度和高度暫定為400,到時候再調(diào)整。最終代碼如下:

[javascript] view plaincopy
  1. Ext.define("Ext.ux.Login", {  
  2.     extend: "Ext.window.Window",  
  3.     singleton: true,  
  4.     title: '簡單的CMS后臺管理系統(tǒng)后臺登錄窗口',  
  5.     width: 400,  
  6.     height: 400  
  7. });  


       接下來,要考慮窗口應(yīng)該包含那些配置項了,窗口應(yīng)是模態(tài)的,不能關(guān)閉,不能調(diào)整大小,關(guān)閉模式為隱藏,隱藏模式為偏移等,因而加入以下代碼:

[javascript] view plaincopy
  1. modal: true,  
  2. closable: false,  
  3. resizable: false,  
  4. closeAction: 'hide',  
  5. hideMode: 'offsets',  

 

      好了,現(xiàn)在要在窗口的initComponent方法內(nèi)定義登錄用的控件了。一般的登錄窗口都包含用戶名、密碼和驗證碼3個文本輸入框,還包含有顯示驗證 碼的圖片、登錄和重置按鈕。因而需要用到的ExtJS控件包括表單面板、圖片、工具欄、按鈕和文本字段。下面要做的是先定義好表單,在擴展內(nèi)加入以下代 碼:

[javascript] view plaincopy
  1.    initComponent: function () {  
  2.        var me = this;  
  3.        me.form = Ext.create(Ext.form.Panel, {  
  4.              
  5.        });  
  6. me.callParent(arguments);  
  7.    }  

 

      代碼中,me的作用是將外部作用域中的this對象保存為本地變量,這樣的好處包括,一是,如果this是window等全局變量,就可以將全局變量變成 本地變量,提高訪問效率,二是可以讓閉包訪問該對象。這寫法在Ext JS文件中始終貫穿其中,本著拿來主義的精神,好東西應(yīng)該學(xué)一下。

      注意create方法中的對象名稱,筆者并沒有使用字符串,這樣就可以直接使用對象,而不需要再去轉(zhuǎn)換表中找對象,可以提高速度,筆者建議這樣寫。

      調(diào)用callParent方法是必須的,不然組件運行會出問題,達(dá)不到預(yù)期效果,具體請參考筆者書中的講解。

       接下來是定義表單的配置項了,筆者習(xí)慣的配置項有以下幾個:

[javascript] view plaincopy
  1. border: false,   
  2. bodyPadding: 5,  
  3. bodyStyle: "background:#DFE9F6",  

 

      代碼中,第一句表示不要邊框,如果喜歡帶有邊框的表單,可以把這項去掉或者修改為true。第二句表示將表單面板向內(nèi)壓縮5像素,這樣表單內(nèi)的組件就不會 和窗口的內(nèi)邊框粘在一起,這個可根據(jù)個人喜好設(shè)置。第三句的作用就是讓表單面板的背景顏色和窗口融合在一起,而不是默認(rèn)的白色,這還是個人喜好問題。

      接著加入表單面板的提交地址,這里定為Account/Login,就是Account控制器的Login方法,代碼如下:

[javascript] view plaincopy
  1. url: "Account/Login",  


      因為表單內(nèi)使用的都是文本字段,因而可以統(tǒng)一做一些定義,如標(biāo)簽寬度為80,標(biāo)簽的分隔符為中文冒號,錨固為0,都不允許為空等,代碼如下:

[javascript] view plaincopy
  1. defaultType: "textfield",  
  2. fieldDefaults: {  
  3.     labelWidth: 80,   
  4. labelSeparator: ":",   
  5. anchor: "0",   
  6. allowBlank: false  
  7. },  

 

      接下來是定義字段了,這個簡單,因為默認(rèn)設(shè)置已經(jīng)定義了幾個配置項,因而余下的就只有字段標(biāo)簽和名稱。驗證碼特殊點,必須是6位字符,代碼如下:

[javascript] view plaincopy
  1. items: [  
  2.     {  
  3.         fieldLabel: "用戶名", name: "UserName"  
  4.     },  
  5.     {  
  6.         fieldLabel: "密碼", name: "Password", inputType: "password"  
  7.     },  
  8.     {  
  9.         fieldLabel: "驗證碼", name: "Vcode", minLength: 6, minLength: 6  
  10.     }  
  11. ]  


      現(xiàn)在要考慮怎么顯示驗證碼圖片,如果直接在表單內(nèi)加入Image控件,會很難控制圖片的位置,因為最好的方式是先套一個容器。因為Img對象的實例在刷新 圖片的時候還要用到,因而最好用一個屬性來指向?qū)ο髮嵗?,這樣就可以通過該屬性在類的內(nèi)部訪問到實例了。在創(chuàng)建表單的前面添加以下創(chuàng)建Img對象實例的代 碼:

[javascript] view plaincopy
  1. me.p_w_picpath=Ext.create(Ext.Img,{  
  2.     src: "/VerifyCode"  
  3. });  

 

      千萬不要在創(chuàng)建表單后面創(chuàng)建,不然在表單內(nèi)插入圖片的時候就找不到對象了。

      代碼中,驗證碼圖片將VerifyCode控制器生成,這個暫時放下,會在后面討論。

      還要實現(xiàn)的是單擊圖片刷新驗證碼,但是查API發(fā)現(xiàn)Img對象居然沒單擊事件。沒關(guān)系,在4.1版本的Ext JS中,修改了事件的定義方式,可以直接為對象生成的HTML元素綁定事件了,只要在監(jiān)聽事件中加入element配置項就行了,這相當(dāng)方法。因而可在創(chuàng) 建Img實例的配置對象中加入以下代碼:

[javascript] view plaincopy
  1. listeners:{  
  2.     click:me.onRefrehImage,  
  3.     element:"el",  
  4.     scope:me  
  5. }  


       代碼中,element配置項中的el就表示要在對象生成的HTML元素中綁定事件,綁定事件為click事件,事件將調(diào)用onRefrehImage方 法。方法只是簡單的刷新圖片,因而使用Img對象的setSrc方法就可以,使用以下代碼順便完成onRefrehImage方法:

[javascript] view plaincopy
  1. onRefrehImage: function () {  
  2.     this.p_w_picpath.setSrc("/VerifyCode?_dc=" + (new Date()).getTime());  
  3. }  

 

      代碼很簡單,使用setSrc方法刷新圖片的src就行了,加上時間戳可防止顯示緩存圖片。

       好了,可以在表單items里加入驗證碼圖片了,代碼如下:

[javascript] view plaincopy
  1. {  
  2.     xtype: "container", height: 80, anchor: "-5", layout: "fit",  
  3.     items: [me.p_w_picpath]  
  4. }  

 

       從代碼可以看到,使用容器的作用就是可以使用fit布局來限制圖片的尺寸,這樣布局就容易多了。

      還要加入一段提示信息,告知用戶驗證碼不區(qū)分大小寫,且如果看不清楚驗證碼圖片,可單擊圖片刷新驗證碼,代碼如下:

[javascript] view plaincopy
  1. {  
  2.     xtype: "container", anchor: "-5", html: "**驗證碼不區(qū)分大小寫,如果看不清楚驗證碼,可單擊圖片刷新驗證碼。"  
  3. }  


      表單余下的就是添加登錄和重置按鈕了,代碼如下:

[javascript] view plaincopy
  1. dockedItems: [{  
  2.     xtype: 'toolbar', dock: 'bottom', ui: 'footer', layout: { pack: "center" },  
  3.     items: [  
  4.         { text: "登錄", width: 80, disabled: true, formBind: true, handler: me.onLogin, scope: me },  
  5.         { text: "重置", width: 80, handler: me.onReset, scope: me }  
  6.     ]  
  7. }]  

 

      在這里使用了dockedItems配置項,目的一是因為介紹Ext JS 4的新功能,二是因為使用這個確實挺方便。代碼中定義了一個工具欄,??课恢糜蒬ock配置項決定,在這里是底部(bottom),工具欄的樣式使用了 ui配置項定義的footer,也就是原來窗口的底部頁腳工具欄,工具欄的布局將使用居中對齊方式。

       登錄按鈕預(yù)設(shè)為禁用的。formBind配置的作用是只有在表單內(nèi)輸入符合要求時才能使用該按鈕,這個設(shè)計在Ext JS4也是新加入的,很方便,不再需要自己去寫代碼實現(xiàn)這個了。登錄按鈕將調(diào)用onLogin方法。重置按鈕很簡單,只是簡單的調(diào)用onReset方法。

       余下要完成的是onLogin和onReset方法。先來完成簡單onReset方法,基本功能就是重置表單,并將焦點移動到第一個文本字段,也就是用戶名那里,還要刷新驗證碼,代碼如下:

[javascript] view plaincopy
  1. onReset: function () {  
  2.     var me = this;  
  3.     me.form.getForm().reset();  
  4.     if (me.form.items.items[0]) {  
  5.         me.form.items.items[0].focus(true, 10);  
  6.     }  
  7.     me.onRefrehImage();  
  8. }  

 

      代碼中要注意的是獲取表單中第一個文本字段的代碼,因為表單在實例化后,items屬性指向的是MixedCollection實例,因為要在其items內(nèi)才能找到文本自動對象。

      接著完成的是onLogin方法,難度也不大, 就是先調(diào)用isValid方法,驗證表單是否符合提交要求,然后調(diào)用submit方法提交。其實不調(diào)用isValid也行,因為登錄按鈕只要在 isValid為true時才能用,不過筆者習(xí)慣如何,多余就多余點吧。代碼如下:

[javascript] view plaincopy
  1. onLogin: function () {  
  2.     var me = this,  
  3.         f = me.form.getForm();  
  4.     if (f.isValid()) {  
  5.         f.submit({  
  6.             waitMsg: "正在登錄,請等待……",  
  7.             waitTitle: "正在登錄",  
  8.             success: function (form, action) {  
  9.                 window.location.reload();  
  10.             },  
  11.             failure: function(){  
  12.             },  
  13.             scope: me  
  14.         });  
  15.     }  
  16. }  

 

      在submit方法內(nèi),waitMsg和waitTitle會顯示一個等待對話框,并用一個遮罩遮住表單,不讓用戶編輯,其中waitMsg就是要顯示的 提示信息,waitTitle就是彈出窗口的標(biāo)題的。不過,在4.1.1版本,這里有bug,筆者已提交至官方論壇,修正方法可參閱http://www.sencha.com/forum/showthread.php?228970-4.1.1-GA-Form-Submit-Problem。這里筆者就不修正了,測試的時候會屏蔽這兩句代碼。

       登錄成功(success配置項)后,會刷新一下頁面,讓頁面寫入驗證信息到Cookie。當(dāng)然,也可以跳轉(zhuǎn)到另外一頁,不過筆者認(rèn)為不如這樣來得簡便,這個稍后會說到。

      登錄失?。╢ailure配置項),只寫了一個空函數(shù)的目的是因為表單的提交返回的數(shù)據(jù)格式是一樣的,處理方式也一樣,因而可使用同一個函數(shù)進(jìn)行處理,但是還沒寫到,因而先保留一個空函數(shù)。

      最后,別忘了將表單加入窗口的items里,這個必須放在調(diào)用callParent之前,不如不會初始化表單,代碼如下:

[javascript] view plaincopy
  1. me.items = [me.form]  

 

      至此,登錄窗口就暫時寫好了,今天的進(jìn)度也完成了。

      嘿嘿,這樣的項目進(jìn)度會郁悶死項目經(jīng)理的。

     懶得上傳文件了,以下是完整的Login.js代碼:

[javascript] view plaincopy
  1. /// <reference path="../Ext.js" />  
  2.   
  3. Ext.define("Ext.ux.Login", {  
  4.     extend: "Ext.window.Window",  
  5.     singleton: true,  
  6.     title: '簡單的CMS后臺管理系統(tǒng)后臺登錄窗口',  
  7.     width: 400,  
  8.     height: 400,  
  9.     modal: true,  
  10.     closable: false,  
  11.     resizable: false,  
  12.     closeAction: 'hide',  
  13.     hideMode: 'offsets',  
  14.   
  15.     initComponent: function () {  
  16.         var me = this;  
  17.   
  18.         me.p_w_picpath = Ext.create(Ext.Img, {  
  19.             src: "/VerifyCode",  
  20.             listeners: {  
  21.                 click: me.onRefrehImage,  
  22.                 element: "el",  
  23.                 scope: me  
  24.             }  
  25.         });  
  26.   
  27.         me.form = Ext.create(Ext.form.Panel, {  
  28.             border: false,  
  29.             bodyPadding: 5,  
  30.             bodyStyle: "background:#DFE9F6",  
  31.             url: "Account/Login",  
  32.             defaultType: "textfield",  
  33.             fieldDefaults: {  
  34.                 labelWidth: 80,  
  35.                 labelSeparator: ":",  
  36.                 anchor: "0",  
  37.                 allowBlank: false  
  38.             },  
  39.             items: [  
  40.                 {  
  41.                     fieldLabel: "用戶名", name: "UserName"  
  42.                 },  
  43.                 {  
  44.                     fieldLabel: "密碼", name: "Password", inputType: "password"  
  45.                 },  
  46.                 {  
  47.                     fieldLabel: "驗證碼", name: "Vcode", minLength: 6, minLength: 6  
  48.                 },  
  49.                 {  
  50.                     xtype: "container", height: 80, anchor: "-5", layout: "fit",  
  51.                     items: [me.p_w_picpath]  
  52.                 },  
  53.                 {  
  54.                     xtype: "container", anchor: "-5", html: "**驗證碼不區(qū)分大小寫,如果看不清楚驗證碼,可單擊圖片刷新驗證碼。"  
  55.                 }  
  56.             ],  
  57.             dockedItems: [{  
  58.                 xtype: 'toolbar', dock: 'bottom', ui: 'footer', layout: { pack: "center" },  
  59.                 items: [  
  60.                     { text: "登錄", width: 80, disabled: true, formBind: true, handler: me.onLogin, scope: me },  
  61.                     { text: "重置", width: 80, handler: me.onReset, scope: me }  
  62.                 ]  
  63.             }]  
  64.         });  
  65.   
  66.         me.items = [me.form]  
  67.   
  68.         me.callParent(arguments);  
  69.   
  70.     },  
  71.   
  72.     onRefrehImage: function () {  
  73.         this.p_w_picpath.setSrc("/VerifyCode?_dc=" + (new Date()).getTime());  
  74.     },  
  75.   
  76.     onReset: function () {  
  77.         var me = this;  
  78.         me.form.getForm().reset();  
  79.         if (me.form.items.items[0]) {  
  80.             me.form.items.items[0].focus(true, 10);  
  81.         }  
  82.         me.onRefrehImage();  
  83.     },  
  84.   
  85.     onLogin: function () {  
  86.         var me = this,  
  87.             f = me.form.getForm();  
  88.         if (f.isValid()) {  
  89.             f.submit({  
  90.                 waitMsg: "正在登錄,請等待……",  
  91.                 waitTitle: "正在登錄",  
  92.                 success: function (form, action) {  
  93.                     window.location.reload();  
  94.                 },  
  95.                 failure: function(){  
  96.                 },  
  97.                 scope: me  
  98.             });  
  99.         }  
  100.     }  
  101.   
  102.   
  103. });  

 

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI