ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)一期
Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS
前往博客園總目錄:ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)一期
經(jīng)過前幾節(jié),我們已經(jīng)解決數(shù)據(jù)庫,模型,DTO,控制器和注入等問題.那么再來看一下登錄邏輯.這里算是前面幾節(jié)的一個(gè)初次試水.
首先我們數(shù)據(jù)庫已經(jīng)有的相應(yīng)的數(shù)據(jù).
模型和DTO已經(jīng)建好,所以我們直接在服務(wù)層添加Login方法就可以了.
在展現(xiàn)層添加Account控制器,注入IUserService接口,調(diào)用Login方法.
然后添加視圖頁面.
運(yùn)行一下,看一下結(jié)果.
除了頁面比較漂亮(哈哈),這些本來都沒有什么好說的,直接上圖,
這里值得注意的是,我們?cè)趧?chuàng)建下面的方法,在調(diào)用接口的的時(shí)候會(huì)報(bào)一個(gè)錯(cuò)誤:web的App_Data/Logs/Logs.txt日志文件中查看到打印到錯(cuò)誤信息屋灌。
public async Task<ListResultDto<UserInfoDto>> GetUsers()
{
var users = await _userRepository.GetAllListAsync();
return new ListResultDto<UserInfoDto>(
users.MapTo<List<UserInfoDto>>()
);
}
錯(cuò)誤提示: Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance.
意思是:映射器未初始化榔幸。 通過適當(dāng)?shù)呐渲谜{(diào)用初始化频伤。 如果您嘗試通過容器或其他方式使用映射器實(shí)例斧散,請(qǐng)確保您沒有任何調(diào)用靜態(tài)Mapper.Map方法鳄虱,如果您使用ProjectTo或UseAsDataSource擴(kuò)展方法鸳惯,請(qǐng)確保您傳入相應(yīng)的IConfigurationProvider實(shí)例捷兰。
原因:Mapper not initialized 映射未初始化
解決:在ApplicationModule類中增加依賴typeof(AbpAutoMapperModule)即可泻红。
using System.Reflection;
using Abp.Modules;
using Abp.AutoMapper;
namespace JCmsErp
{
[DependsOn(typeof(JCmsErpCoreModule), typeof(AbpAutoMapperModule))]
public class JCmsErpApplicationModule : AbpModule
{
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
}
}
另外上面這個(gè)提示窗是不是很漂亮,登錄頁面的設(shè)計(jì)樣式都是自己寫的,自己這個(gè)彈窗,只是abp自己封裝.我們來看一下具體的代碼.
abp.message.confirm(
'請(qǐng)輸入密碼.', //確認(rèn)提示
'確定?',//確認(rèn)提示(可選參數(shù))
function (isConfirmed) {
if (isConfirmed) {
//...delete user 點(diǎn)擊確認(rèn)后執(zhí)行
}
}
);
其實(shí)abp封裝很多js函數(shù)庫,這讓我不得不感嘆土牛(土耳其牛人)真是牛啊!看下圖左邊部分js文件
包括像abp.jquery.js,ABP服務(wù)端支持標(biāo)準(zhǔn)的ajax的請(qǐng)求/輸出。建議大家使用abp.jquery.js中提供的ajax請(qǐng)求方法或颊,這個(gè)方法基于jquery的ajax方法砸紊,可以自動(dòng)處理服務(wù)端的異常信息,當(dāng)然囱挑,如果你對(duì)js很熟練的話醉顽,也可以根據(jù)自己的需要寫ajax。你也可以使用jquery的ajax方法調(diào)用平挑,但是需要設(shè)置一下默認(rèn)請(qǐng)求參數(shù)游添,dataType 設(shè)置為 'json', type 設(shè)置為 'POST' and contentType 設(shè)置為 'application/json,在發(fā)送請(qǐng)求時(shí)需要將js對(duì)象轉(zhuǎn)換成json字符串通熄,和$.ajax一樣唆涝,你也可以傳遞參數(shù)覆蓋abp.ajax的默認(rèn)參數(shù)abp.ajax返回一個(gè)promise類型.Login上標(biāo)記了 HttpPost 特性 abp.ajax默認(rèn)以 POST 方式請(qǐng)求. 返回值被簡(jiǎn)化成了一個(gè)匿名對(duì)象。
消息
用于向用戶顯示對(duì)話框唇辨,展示消息或者得到用戶的確認(rèn),ABP默認(rèn)采用的sweetalert庫實(shí)現(xiàn)的對(duì)話框信息廊酣,使用時(shí)你需要引用sweetalert的樣式和js,在我的登錄頁面里面已經(jīng)引用了,并且引用abp.sweet-alert.js就可以使用下列API了:
abp.message.info('some info message', 'some optional title');
abp.message.success('some success message', 'some optional title');
abp.message.warn('some warning message', 'some optional title');
abp.message.error('some error message', 'some optional title');
abp.message.confirm(
'User admin will be deleted.', //確認(rèn)提示
'Are you sure?',//確認(rèn)提示(可選參數(shù))
function (isConfirmed) {
if (isConfirmed) {
//...delete user 點(diǎn)擊確認(rèn)后執(zhí)行
}
}
);
用戶界面的繁忙提示
設(shè)置一個(gè)半透明層赏枚,阻止點(diǎn)擊頁面元素亡驰,可以覆蓋局部或者整個(gè)頁面晓猛,例子如下:
abp.ui.block(); //覆蓋整個(gè)頁面
abp.ui.block($('#MyDivElement')); //覆蓋指定元素,可以把jquery對(duì)象作為參數(shù)
abp.ui.block('#MyDivElement'); //或者直接使用選擇器參數(shù)
abp.ui.unblock(); //整個(gè)頁面解除覆蓋
abp.ui.unblock('#MyDivElement'); //指定元素解除覆蓋
UI Block API使用blockUI這個(gè)js庫來實(shí)現(xiàn)效果的凡辱,如果使用這個(gè)api需要在頁面引用blockUI的js庫和abp.blockUI.js文件戒职。
UI Busy API 指示頁面繁忙的API,如ajax請(qǐng)求中:
abp.ui.block = function (elm) {
if (!elm) {
$.blockUI();
} else {
$(elm).block();
}
};
abp.ui.unblock = function (elm) {
if (!elm) {
$.unblockUI();
} else {
$(elm).unblock();
}
};
abp.ui.setBusy('#MyLoginForm');
abp.ui.clearBusy('#MyLoginForm');
Js日志接口
這個(gè)主要是對(duì)瀏覽器console.log('...') 進(jìn)行的包裝透乾,可以支持所有瀏覽器洪燥,你可以通過設(shè)置abp.log.level來控制日志輸出,和服務(wù)端一樣续徽,如設(shè)置了abp.log.levels為INFO時(shí)就不會(huì)輸出debug日志了蚓曼,你也可以根據(jù)你的需要定制重新這些API。
abp.notify.success = function (message, title, options) {
abp.log.warn('abp.notify.success is not implemented!');
};
abp.notify.info = function (message, title, options) {
abp.log.warn('abp.notify.info is not implemented!');
};
abp.notify.warn = function (message, title, options) {
abp.log.warn('abp.notify.warn is not implemented!');
};
abp.notify.error = function (message, title, options) {
abp.log.warn('abp.notify.error is not implemented!');
};
格式化字符串(abp.utils.formatString)
和C#的string.Format一樣的用法
/* Formats a string just like string.format in C#.
* Example:
* abp.utils.formatString('Hello {0}','Tuana') = 'Hello Tuana'
************************************************************/
abp.utils.formatString = function () {
if (arguments.length < 1) {
return null;
}
var str = arguments[0];
for (var i = 1; i < arguments.length; i++) {
var placeHolder = '{' + (i - 1) + '}';
str = abp.utils.replaceAll(str, placeHolder, arguments[i]);
}
return str;
};
最后,當(dāng)然我們登錄頁面也可以改一下.這樣就更簡(jiǎn)潔了.
var url = "/Account/Login";
//構(gòu)建要傳輸?shù)膮?shù)對(duì)象
var newPerson = {
userName:$("#userName").val(),
password:$("#password").val() }
};
//調(diào)用abp的ajax方法
abp.ajax({
url:url,
data: JSON.stringify(newPerson) //轉(zhuǎn)換成json字符串
}).done(function (data) {
abp.message.warn('用戶名或密碼錯(cuò)誤!', '登錄失敗');
});
至此,我們登錄邏輯,和JavaScript封裝模塊就全部完成了,其實(shí)abp提示窗還蠻好看的,大家也可以借鑒一下在自己的項(xiàng)目里面.
下面說下JavaScript的封裝钦扭。
AJAX操作問題
現(xiàn)代的應(yīng)用經(jīng)常會(huì)使用AJAX纫版,尤其是單頁應(yīng)用,幾乎是和服務(wù)器通信的唯一手段客情,執(zhí)行AJAX通常會(huì)有以下步驟:
基本上:為了執(zhí)行一個(gè)AJAX調(diào)用其弊,首先你要在客戶端提供一個(gè)可供請(qǐng)求的URL,選取提交數(shù)據(jù)和一個(gè)方法(GET,POST,PUT,DELETE)膀斋。
等待調(diào)用完成后梭伐,處理返回結(jié)果。當(dāng)執(zhí)行AJAX調(diào)用服務(wù)器端的時(shí)候仰担,可能會(huì)有錯(cuò)誤(一般是網(wǎng)絡(luò)錯(cuò)誤)糊识。當(dāng)然也有可能是服務(wù)器端產(chǎn)生了一些錯(cuò)誤,對(duì)于這些錯(cuò)誤會(huì)摔蓝,服務(wù)器會(huì)返回一個(gè)失敗的響應(yīng)并且附上錯(cuò)誤消息給客戶端赂苗。
客戶端代碼應(yīng)該處理這些錯(cuò)誤,并且可以選擇通知用戶(可以顯示一個(gè)錯(cuò)誤對(duì)話框)贮尉。如果沒有錯(cuò)誤且服務(wù)器端返回了數(shù)據(jù)拌滋,客戶端必須處理它。還有你應(yīng)該限制頁面的某個(gè)區(qū)域(或者整個(gè)頁面)猜谚,并顯示一個(gè)忙碌的指示直到AJAX操作完成败砂。
服務(wù)器端在得到請(qǐng)求后執(zhí)行服務(wù)器端代碼,捕獲異常并返回一個(gè)有效的響應(yīng)給客戶端魏铅。在錯(cuò)誤情況下昌犹,可以選擇發(fā)送錯(cuò)誤消息給客戶端。如果是驗(yàn)證錯(cuò)誤览芳,服務(wù)器端可以添加驗(yàn)證錯(cuò)誤的驗(yàn)證信息斜姥。在成功情況下,可以發(fā)送返回值給客戶端。
ABP的方式
由于使用 abp.ajax 函數(shù)對(duì)AJAX調(diào)用進(jìn)行了封裝疾渴, 所以ABP能自動(dòng)化這些步驟。下面是一個(gè)AJAX調(diào)用示例:
var newPerson = {
name: 'Dougles Adams',
age: 42
};
abp.ajax({
url: '/People/SavePerson',
data: JSON.stringify(newPerson)
}).done(function(data) {
abp.notify.success('created new person with id = ' + data.personId);
});
abp.ajax得到 options 作為對(duì)象屯仗。你可以傳遞任何有效的jQuery的 $.ajax 函數(shù)中的參數(shù)搞坝。有一些默認(rèn)參數(shù):dataType 是 json,type是 POST魁袜,還有 contentType是 application/json(在發(fā)送數(shù)據(jù)到服務(wù)器端之前桩撮,我們需要調(diào)用 JSON.stringify 將腳本對(duì)象轉(zhuǎn)換為JSON字符串)。通過對(duì)apb.ajax傳遞options可以覆蓋默認(rèn)值峰弹。
abp.ajax返回promise店量。因此,你可以寫這些處理函數(shù):done鞠呈,fail融师,then等等。在這個(gè)例子中蚁吝,我們對(duì) PeopleController's SavePerson action 發(fā)送了一個(gè)簡(jiǎn)單的AJAX請(qǐng)求旱爆。在 done 處理函數(shù)中,我們對(duì)新創(chuàng)建的person取得了它的主鍵id并且顯示了創(chuàng)建成功的通知窘茁。讓我們看看 MVC Controller:
public class PeopleController : AbpController
{
[HttpPost]
public JsonResult SavePerson(SavePersonModel person)
{
//TODO: 保存新創(chuàng)建的person到數(shù)據(jù)庫并且返回person的id
return Json(new {PersonId = 42});
}
}
正如你猜測(cè)的 SavePersonModel 包含了Name和Age屬性怀伦。SavePerson 被標(biāo)記為 HttpPost 特性,因?yàn)閍bp.ajax默認(rèn)方法是POST山林。通過返回了匿名對(duì)象簡(jiǎn)化了方法實(shí)現(xiàn)房待。
這個(gè)看上去很簡(jiǎn)單直白,但是ABP在背后做了很多重要的處理驼抹。讓我們深入了解一下:
AJAX 返回消息
即使我們直接的返回了一個(gè)帶有PersonId = 2 的對(duì)象桑孩,ABP也會(huì)使用 MvcAjaxResponse 對(duì)象來包裝它。事實(shí)上AJAX響應(yīng)返回的內(nèi)容應(yīng)該像下面一樣:
{
"success": true,
"result": {
"personId": 42
},
"error": null,
"targetUrl": null,
"unAuthorizedRequest": false,
"__abp": true
}
在這里所有的屬性都是駝峰命名的(因?yàn)檫@在JavaScript中是慣例)砂蔽,即使在服務(wù)端代碼中是PascalCased的洼怔。下面解釋一下所有的字段:
success:boolean類型的值(true或者false),用來表示操作的成功狀態(tài)左驾。如果是ture镣隶,abp.ajax會(huì)解析該promise并且調(diào)用 done 函數(shù)。如果是false(在方法被調(diào)用的時(shí)候诡右,如果有個(gè)異常被拋出)安岂,它會(huì)調(diào)用 fail 函數(shù)并且使用 abp.message.error 函數(shù)顯示 error 消息。
result:控制器的action的實(shí)際返回值帆吻。如果success是ture并且服務(wù)器發(fā)送了返回值那么它才是有效的域那。
error:如果success是false,這個(gè)字段是一個(gè)包含 message和details 字段的對(duì)象。
targetUrl:如果需要的話次员,這提供了一種可能性:服務(wù)器端發(fā)送一個(gè)URL到客戶端败许,使客戶端可以重定向到其它的URL。
unAuthorizedRequest:這提供了一種可能性:服務(wù)器端發(fā)送通知給客戶端該操作未被授權(quán)淑蔚,或者是未認(rèn)證用戶市殷。如果該值是true,那么abp.ajax會(huì) reloads 當(dāng)前的頁面刹衫。
__abp:通過ABP包裝響應(yīng)返回的特殊簽名醋寝。你自己不需要用到它,但是abp.ajax會(huì)處理它带迟。
這種格式的對(duì)象會(huì)被 abp.ajax 函數(shù)識(shí)別且處理音羞。abp.ajax會(huì)得到控制器的實(shí)際返回值(一個(gè)帶有personid屬性的對(duì)象),如果沒有錯(cuò)誤的話仓犬,那么你會(huì)在done函數(shù)中處理返回值嗅绰。
處理錯(cuò)誤
正如上面所述,ABP在服務(wù)器端處理異常婶肩,并且返回一個(gè)帶有錯(cuò)誤消息的對(duì)象办陷。如下所示:
{
"targetUrl": null,
"result": null,
"success": false,
"error": {
"message": "An internal error occured during your request!",
"details": "..."
},
"unAuthorizedRequest": false,
"__abp": true
}
正如你看到的,success是false 并且 result是null律歼。abp.ajax處理這個(gè)對(duì)象民镜,并且使用abp.message.error函數(shù)來顯示錯(cuò)誤消息給用戶。如果你的服務(wù)器端代碼拋出了 UserFriendlyException 類型的異常险毁。它會(huì)直接的顯示異常信息給用戶制圈。否則,它會(huì)隱藏實(shí)際的錯(cuò)誤(將錯(cuò)誤寫入日志)畔况,并且顯示一個(gè)標(biāo)準(zhǔn)的“服務(wù)器內(nèi)部錯(cuò)誤...”信息給用戶鲸鹦。所有的這些都是ABP自動(dòng)處理的。
你可能想為某個(gè)特別的AJAX調(diào)用禁止顯示消息跷跪,那么添加 ** abpHandleError: false** 到 abp.ajax的options馋嗜。
HTTP狀態(tài)碼
在異常發(fā)生的時(shí)候,ABP會(huì)返回給定的HTTP狀態(tài)碼:
401:未經(jīng)身份驗(yàn)證的請(qǐng)求(沒有登錄吵瞻,但是服務(wù)器端需要身份驗(yàn)證)葛菇;
403:未授權(quán)的請(qǐng)求;
500:所有其它類型的異常橡羞。
6.6.2.5 WrapResult和DontWrapResult特性
使用 WrapResult和DontWrapResult 特性眯停,可以對(duì)控制器的某個(gè)action或者所有的action來控制包裝。
ASP.NET MVC 控制器
如果返回的類型是 JsonResult(或者Task<JsonResult>)卿泽,那么ABP會(huì)默認(rèn)包裝ASP.NET MVC action的返回結(jié)果莺债。你可以使用 WrapResult 特性來改變它。如下所示:
public class PeopleController : AbpController
{
[HttpPost]
[WrapResult(WrapOnSuccess = false, WrapOnError = false)]
public JsonResult SavePerson(SavePersonModel person)
{
//TODO: 保存新創(chuàng)建的person到數(shù)據(jù)庫并且返回person的id
return Json(new {PersonId = 42});
}
}
作為一個(gè)快速開發(fā)方式,我們只能使用 [DontWrapResult] 特性在這個(gè)相同的示例上齐邦。
你可以在啟動(dòng)配置里面改變這個(gè)默認(rèn)的行為(使用 Configuration.Modules.AbpMvc()...)椎侠。
ASP.NET Web API 控制器
如果action被成功執(zhí)行,ABP 不會(huì)默認(rèn)包裝 Web API Action的返回結(jié)果措拇。如果需要的話肺蔚,你可以添加WrapResult特性到action或者控制器上。但是它會(huì) 包裝異常儡羔。
你可以在啟動(dòng)配置里面改變這個(gè)默認(rèn)的行為(使用 Configuration.Modules.AbpWebApi()...)。
動(dòng)態(tài)Web API層
默認(rèn) ABP會(huì) 包裝 動(dòng)態(tài)Web API層的所有方法璧诵。你可以在你應(yīng)用服務(wù)的接口上使用 WrapResult和DontWrapResult 特性來改變這個(gè)行為汰蜘。
你可以在啟動(dòng)配置里面改變這個(gè)默認(rèn)的行為(使用 Configuration.Modules.AbpWebApi()...)。
ASP.NET Core 控制器
ABP會(huì)自動(dòng)包裝JsonResult之宿,ObjectRes以及那些沒有實(shí)現(xiàn)IActionResult對(duì)象族操。詳情請(qǐng)查閱ASP.NET Core文檔。
你可以在啟動(dòng)配置里面改變這個(gè)默認(rèn)的行為(使用 using Configuration.Modules.AbpAspNetCore()...)比被。
動(dòng)態(tài)Web API層
雖然ABP提供了一種調(diào)用Ajax的簡(jiǎn)單機(jī)制色难,但是在真實(shí)世界的應(yīng)用中,為每個(gè)Ajax調(diào)用編寫javascript函數(shù)是很經(jīng)典的等缀。例如:
//創(chuàng)建一個(gè)抽象了Ajax調(diào)用的function
var savePerson = function(person) {
return abp.ajax({
url: '/People/SavePerson',
data: JSON.stringify(person)
});
};
//創(chuàng)建一個(gè)新的 person
var newPerson = {
name: 'Dougles Adams',
age: 42
};
//保存該person
savePerson(newPerson).done(function(data) {
abp.notify.success('created new person with id = ' + data.personId);
});
這是一個(gè)最佳實(shí)踐枷莉,但是對(duì)每個(gè)AJAX調(diào)用函數(shù)都這樣做,那是耗時(shí)且乏味的尺迂。對(duì)于應(yīng)用服務(wù)和控制器笤妙,ABP能夠自動(dòng)的生成這些函數(shù)。
詳情請(qǐng)閱讀動(dòng)態(tài)Web API層文檔和ASP.NET Core文檔噪裕。
Javascript Notification API
當(dāng)一些事情發(fā)生的時(shí)候蹲盘,我們喜歡顯示一些別致的能夠自動(dòng)消失的通知,例如膳音,當(dāng)某個(gè)記錄被保存或者某個(gè)問題發(fā)生的時(shí)候召衔。ABP定義了標(biāo)準(zhǔn)的API實(shí)現(xiàn)了該功能。
abp.notify.success('a message text', 'optional title');
abp.notify.info('a message text', 'optional title');
abp.notify.warn('a message text', 'optional title');
abp.notify.error('a message text', 'optional title');
作為通知庫的 自定義選項(xiàng)祭陷,它也能夠取得第3個(gè)參數(shù)(對(duì)象)苍凛。
通知API默認(rèn)是使用toastr庫實(shí)現(xiàn)的。要使toastr生效颗胡,你應(yīng)該引用toastr的css和javascript文件毫深,然后再在頁面中包含abp.toastr.js作為適配器。一個(gè)toastr成功通知如下所示:
你也可以用你最喜歡的通知庫實(shí)現(xiàn)通知毒姨。只需要在自定義javascript文件中重寫所有的函數(shù)哑蔫,然后把它添加到頁面中而不是abp.toastr.js中(你可以檢查該文件看它是否實(shí)現(xiàn),這個(gè)相當(dāng)簡(jiǎn)單)。
abp.message簡(jiǎn)介
消息API被用來向用戶顯示一個(gè)消息或者從用戶那里得到一個(gè)確認(rèn)闸迷。
消息API默認(rèn)實(shí)現(xiàn)方式是使用了sweetalert庫嵌纲。使用時(shí)你需要引用sweetalert的樣式和js,然后把 abp.sweet-alert.js 作為適配器包含到你的頁面中腥沽。
顯示消息
如下所示:
abp.message.info('some info message', 'some optional title');
abp.message.success('some success message', 'some optional title');
abp.message.warn('some warning message', 'some optional title');
abp.message.error('some error message', 'some optional title');
成功的消息框顯示如下:
Confirmation對(duì)話框
如下所示:
abp.message.confirm(
'User admin will be deleted.', //確認(rèn)提示
'Are you sure?',//確認(rèn)提示(可選參數(shù))
function (isConfirmed) {
if (isConfirmed) {
//...delete user 點(diǎn)擊確認(rèn)后執(zhí)行
}
}
);
第二個(gè)參數(shù)(標(biāo)題)是可選的(所以逮走,回調(diào)函數(shù)可以作為第二個(gè)參數(shù))。
確認(rèn)消息框顯示如下:
ABP在內(nèi)部使用了消息API今阳,例如:如果某個(gè)AJAX調(diào)用失敗师溅,那么它會(huì)調(diào)用abp.message.error。
Javascript UI Block & Busy API
ABP提供了有用的API盾舌,使整個(gè)頁面或者頁面的某個(gè)部分被遮罩層覆蓋實(shí)現(xiàn)阻塞或者繁忙指示(使用加載圖標(biāo)表示繁忙)墓臭。
UI Block API
這個(gè)API使用一個(gè)透明的遮罩層(透明度可調(diào)節(jié))來遮住整個(gè)頁面或者該頁面的某個(gè)元素。因此用戶不能夠點(diǎn)擊妖谴。當(dāng)你保存表單或者加載某個(gè)區(qū)域時(shí)(某個(gè)層或者整個(gè)頁面)窿锉,這是相當(dāng)有用的。
如下所示:
abp.ui.block(); //遮住整個(gè)頁面
abp.ui.block($('#MyDivElement')); //遮罩某個(gè)元素膝舅,在這里可以使用jQuery選擇器選擇元素..
abp.ui.block('#MyDivElement'); //..或者直接指定元素
abp.ui.unblock(); //解除遮罩
abp.ui.unblock('#MyDivElement'); //對(duì)指定元素解除遮罩
UI Block API 默認(rèn)是使用jQuery插件block UI來實(shí)現(xiàn)的嗡载。為了能正常運(yùn)行,你需要引用腳本文件仍稀,然后包含 abp.blockUI.js 文件作為適配器到你的頁面中洼滚。
UI Busy API
該API被用來指示某些頁面或者元素正在忙碌(加載)。例如:當(dāng)你提交表單數(shù)據(jù)到服務(wù)器的時(shí)候技潘,你可能想要遮罩這個(gè)表單并顯示一個(gè)忙碌的指示器判沟。
如下所示:
abp.ui.setBusy('#MyLoginForm');
abp.ui.clearBusy('#MyLoginForm');
參數(shù)應(yīng)該是一個(gè)jQuery選擇器(如:#MyLoginForm)或者jQuery對(duì)象(如:$('#MyLoginForm'))。為了使整個(gè)頁面都是在繁忙狀態(tài)崭篡,你應(yīng)該傳遞null或者body作為選擇器挪哄。
setBusy函數(shù)能夠傳入一個(gè)promise(作為第二個(gè)參數(shù))并且自動(dòng)的清除busy,當(dāng)該promise完成的時(shí)候琉闪。如下所示:
abp.ui.setBusy(
$('#MyLoginForm'),
abp.ajax({ ... })
);
由于abp.ajax返回的是promise迹炼,所以我們能直接使用它作為參數(shù)。如果你想了解更多關(guān)于promise的資料颠毙,請(qǐng)查閱jQuery的Deferred斯入。setBusy對(duì)Q提供支持(以及angulars的$http服務(wù))。
UI Busy API 使用spin.js實(shí)現(xiàn)的蛀蜜。為使其正常運(yùn)行刻两,你應(yīng)該引用該腳本文件,然后在你的頁面中包含 abp.spin.js 作為適配器滴某。
ABP表現(xiàn)層 - 事件總線EventBUS
簡(jiǎn)介
Pub/Sub 事件模型被廣泛的應(yīng)用在客戶端磅摹。ABP包含了一個(gè) 簡(jiǎn)單的全局事件總線 用來注冊(cè)事件并且觸發(fā)事件滋迈。
注冊(cè)事件
你可以使用 abp.event.on 來 注冊(cè) 一個(gè) 全局事件 。示例如下:
abp.event.on('itemAddedToBasket', function (item) {
console.log(item.name + ' is added to basket!');
});
第一個(gè)參數(shù)是 該事件的唯一名稱户誓。另一個(gè)參數(shù)是 回調(diào)函數(shù)饼灿,當(dāng)指定的事件被觸發(fā)后將調(diào)用該參數(shù)。
你可以使用 abp.event.off 方法來 卸載 已注冊(cè)的事件帝美。
注意:為了能夠卸載指定的事件碍彭,應(yīng)該提供相同的事件函數(shù)。
正如上面的示例所展示的悼潭,你應(yīng)該將回調(diào)函數(shù)設(shè)置為一個(gè)變量庇忌,然后在 on和off 中使用它。
觸發(fā)事件
abp.event.trigger 被用來觸發(fā)全局事件舰褪。觸發(fā)一個(gè)已注冊(cè)的事件的代碼如下:
abp.event.trigger('itemAddedToBasket', {
id: 42,
name: 'Acme Light MousePad'
});
第一個(gè)參數(shù)是 該事件的唯一名稱漆枚。第二個(gè)是(可選的)事件參數(shù)。你可以添加任何數(shù)量的參數(shù)抵知,并且在回調(diào)方法中獲得它們。
ABP表現(xiàn)層 - Javascript 日志 API
簡(jiǎn)介
當(dāng)你想要在客戶端寫一些簡(jiǎn)單的日志的時(shí)候软族,你可以使用 console.log('...') API刷喜。但是,它不是所有的瀏覽器都支持該API立砸,并且該函數(shù)也可能破壞你的腳本掖疮。所以,在使用的時(shí)候你首先應(yīng)該檢查console是否有效颗祝。還有浊闪,你可能想在其它地方寫日志。甚至你可能對(duì)寫日志的等級(jí)也有要求螺戳。ABP定義了安全的日志函數(shù):
abp.log.debug('...');
abp.log.info('...');
abp.log.warn('...');
abp.log.error('...');
abp.log.fatal('...');
你可以通過設(shè)置 abp.log.level 對(duì) abp.log.levels 中的某個(gè)日志等級(jí)進(jìn)行更改(例如:abp.log.levels.INFO 不會(huì)記錄調(diào)試日志)搁宾。這些函數(shù)默認(rèn)將日志記錄到了瀏覽器的控制臺(tái)里了。但如果你需要的話倔幼,你也可以重寫或者擴(kuò)展這個(gè)行為盖腿。
ABP表現(xiàn)層 - 其他工具函數(shù)OtherUtilities
ABP提供了一些通用的工具函數(shù)。
abp.utils.createNamespace
用于創(chuàng)建更深的命名空間损同。假設(shè)我們有一個(gè)基命名空間 abp翩腐,然后想要?jiǎng)?chuàng)建或者獲得 abp.utils.strings.formatting 命名空間。不需要像下面這樣寫:
//創(chuàng)建或獲得namespace
abp.utils = abp.utils || {};
abp.utils.strings = abp.utils.strings || {};
abp.utils.strings.formatting = abp.utils.strings.formatting || {};
//給該namespace添加一個(gè)function
abp.utils.strings.formatting.format = function() { ... };
我們可以這樣寫:
var formatting = abp.utils.createNamespace(abp, 'utils.strings.formatting');
//給該namespace添加一個(gè)function
formatting.format = function() { ... };
這樣即安全又簡(jiǎn)單的創(chuàng)建了更深層次的命名空間膏燃。注意茂卦,第一個(gè)參數(shù)是必須存在的根命名空間。
abp.utils.formatString
近似于C#中的string.Format()方法组哩。示例如下:
var str = abp.utils.formatString('Hello {0}!', 'World'); //str = 'Hello World!'
var str = abp.utils.formatString('{0} number is {1}.', 'Secret', 42); //str = 'Secret number is 42'
返回簡(jiǎn)書總目錄:ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)一期
前往博客園總目錄:ABP+AdminLTE+Bootstrap Table權(quán)限管理系統(tǒng)一期