在LawAndRegulation項目中添加導航路由(Abp添加菜單)對應的客戶端頁面。javascript
建立文件
客戶端頁面在Abp模板項目中默認存放在Abp/Main/views文件夾下,在項目中咱們建立屬於字典管理的新文件夾,名字命名爲DictionaryManger。css
在文件夾中建立文件index.cshtml和同名的js文件index.js。html
建立的index.cshtml文件中只須要編寫頁面內容部分,idnex.js中編寫當前頁面邏輯。前端
建立index.cshtml須要注意:java
- 建立時選擇「帶有佈局的MVC5視圖頁」選項,選擇合適的母版(Views/Shared/_Layout.cshtml);
- 刪除原有內容;
一樣添加index.js文件。node
編輯index.cshtml
在視圖頁面中編寫你的html內容,在Abp母版項目中已經引入了Bootstrap,項目DictionaryManager在編寫頁面內容時,使用Bootstrap做爲前端開發框架。jquery
在項目的Bundle.config文件中已經經過文件夾引入的方式引入了/App/Main文件夾下全部css文件因此頁面編寫須要編寫的css能夠直接在index.cshtml項目所在目錄下建立文件添加,在本項目中咱們添加了dicCommon.css文件。angularjs
頁面中使用Bootstrap模態框,想要詳細學習模態框,請移步這裏,有詳細的使用介紹。bootstrap
css文件中定義了不少自定義樣式,這些樣式中的單位存在px和em,存在這樣的問題是由於部份內容繼承自原有代碼,尚未時間進行統一更改,單位之間換算參考連接,這部份內容尚未進行驗證。按照文中介紹,默認狀況下1em=16px,但em是相對單位因此若是父元素定義font-size字段那麼1em=父元素定義的大小。數組
添加html,代碼以下:
<form id="dicForm" runat="server" ng-controller="app.views.dictionarymanager.index as vm"> <div class="row"> <div class="col-xs-12 dic_header" id="dicHeaderBtn"> <button type="button" class="btn btn-primary pull-left" id="btnAddDicCategory" ng-disabled="btnAddDicCategoryDisabled"> 新增字典分類 </button> <button type="button" class="btn btn-primary pull-left" id="btnAddDic" ng-disabled="btnAddDicDisabled" ng-click="AddDictinary()"> 新增字典 </button> <button type="button" class="btn btn-primary pull-left" id="btnEditDic" ng-disabled="btnEditDicDisabled"> 編輯 </button> <button type="button" class="btn btn-primary pull-left" id="btnDeleteDic" ng-disabled="btnDeleteDicDisabled"> 刪除 </button> <button type="button" class="btn btn-primary pull-left" id="btnExport" ng-disabled="btnExportDisabled"> 導出 </button> <button type="button" class="btn btn-primary pull-left" id="btnImport"> 導入 </button> </div> <div class="col-xs-12 d-p-l"> <div class="col-sm-4 col-lg-3 dic_noderow" id="dicNodeRow"> <div id="dicTree"> </div> </div> <div class="col-sm-8 col-lg-9 d-p-l" id="divDetail"> <iframe id="showInfomation" ng-src="{{srcValue}}" name="iframeSelf"></iframe> </div> </div> </div> </form>
上面代碼爲bootstrap(css/html開源框架),其中dic-header、d-p-l、dic-noderow爲自定義css其餘爲bootstrap原生要素及屬性,若是想進一步學習bootstrap使用能夠查看連接。上面代碼除了使用佈局及按鈕以外,還使用了模態框,關於模態框菜鳥有介紹,移步連接。class內包含col-sm-12等col開頭的樣式,這些樣式爲bootstrap的網格系統,網格系統的具體介紹請查看上面bootstrap連接。
視圖中涉及到的樣式
bootstrap默認樣式介紹:
- btn:原始按鈕樣式;
- btn-primary:基本按鈕樣式;
- pull-left:總體左滑動;相似於左對齊,好比頁面中控件隱藏,則右側控件像左側滑動;
- col-xm-12在小型設備上的佈局,視圖總計爲12,class中存在這個預約義類的要素至關於充滿整個屏幕;
- col-lg-3爲在大型設備上佈局,結合上面的col-xm-使用就能夠達到響應式(一個站點適應多個終端)的佈局;
這些默認樣式具體定義了什麼能夠查看bootstrap-theme.css(能夠經過下載bootstrap框架獲得這個文件)中源碼進行查看。
自定義樣式:
.r-p-l { padding-left: 10px; } div.col-xs-12.dic_header { padding-top: 10px; margin-left: 15px; padding-bottom: 50px; } div.dic_noderow, #dicTree { overflow-x: hidden; overflow-y: auto; max-width: 500px; }
自定義樣式中咱們定義瞭如下屬性:
- padding-left、padding-top、padding-bottom:盒子模型的內邊距;
- margin-left:盒子模型的外邊距;
- overflow-x、overflow-y:內容溢出是否裁剪;
視圖中涉及的標籤
- button:按鈕標籤;
- form:負責數據採集的一組標籤;
- div:將視圖劃分爲不一樣區域;
還有其餘bootstrap自定義樣式,這裏再也不詳細介紹,若是有時間開設專門的博客介紹bootstrap。
要素包含ng-字符的屬性屬於angular,這些屬性大部分把ng-去掉即爲要素原生屬性,咱們在視圖中添加這些屬性,就能夠在控制器中直接對這些屬性進行賦值,下一節咱們詳細介紹這些屬性的使用。
編輯index.js
當即執行函數-若是已經掌握跳過
首先在inde.js文件中編寫一個當即執行函數,當即執行函數就是在函數定義的地方直接執行這個函數。做用及好處能夠概括爲隔離做用域,在私有做用域內變量及函數不會被污染,至關於起到命名空間的做用。
編寫方式有如下幾種(詳細瞭解參考連接):
//user () operational character (function(){})(); (function(){}()); //user ! operational character !(function(){})(); //uer + operational character +(function(){})(); //uer + operational character -(function(){})(); //uer + operational character var temp=(function(){})();
在咱們的js文件中咱們使用了第一種方式編寫以及執行函數。
angular模塊module
在js文件的當即執行函數中,咱們首先定義一個模塊,在angularjs中模塊是應用程序中不一樣部分的容器,在這些容器中咱們能夠添加controllers(控制器)、services(服務)、filters(過濾器)、directives(指令)等內容。
angular中模塊經過angular.mudole(name,requires,configfn)方法建立:
- name:模塊的名稱,與視圖中html標籤的ng-app屬性相關聯;
- requires:模塊的依賴關係,若是在調用方法時沒有設置此參數,那麼方法默認爲獲取這個模塊;若是建立新模塊並肯定沒有依賴關係,那麼須要設置這個參數爲[]數組;
- configfn:負責在模塊初始化時作一些配置,參數是方法或者數組,這個參數是數組,那麼最後一個參數必須是方法。
angular控制器controller
控制器是對視圖的數據和時間處理函數進行掛載,同時進行必定的業務功能的底層封裝和處理,起到的做用就是加強視圖,在視圖的做用於中增長額外的功能,咱們用它來給做用於對象設置初始化狀態,添加自定義行爲。
建立完成angular模塊後,調用模塊方法controller建立控制器,controller的參數組成爲:
- controllerName:控制器名稱,控制器名稱和ag-controller屬性值相對應;
- controllerConstructor:第二個參數爲一個回調函數,用於執行構造函數初始化內容;
angular做用域scope
在項目代碼中,controller的參數是一個scope對象,scope是視圖與控制器之間的紐帶,scope是一個javascript對象,scope能夠定義屬性和方法,這些屬性和方法能夠在視圖和控制器之間使用。
調用標籤事件
通用事件
//angular angular.element("#id").click(); //jquery $("#id").click(); //原生 document.getElementById("#id").trigger("click");
標籤特定事件
//angular angular.element("#id").on("eventName",function(event,data){}); //jquery $("#id").on("eventName",function(event,data){});
基於bootstrap的jQuery多級列表樹插件
裝載及初始化插件:
//初始化treeview angular.element("#dicTree").treeview({ data: getDictinary(), levels: 2, color: '#000000', backColor: '#FFFFFF', href:'#node-1' }); function getDictinary() { var tree = [ { text: "Parent 1", nodes: [{text: "Child 1",nodes: [{text: "Grandchild 1"}]}] } ]; return tree; }
以上爲最簡單結構,還有其餘擴展屬性能夠查看連接,節點屬性一節中有詳細的介紹。
添加treeview控件的節點選擇事件:
angular.element("#dicTree").on('nodeSelected', function (event, data) { alert(data.text); });
當節點被選擇後能夠觸發事件調用該方法,在本項目中爲了顯示節點的詳細信息。
持久化當前選擇節點內容
所謂的持久化內容,也就是在當前視圖的生命週期內保存視圖中須要的內容。
在節點選擇事件中對視圖中form表單的隱藏標籤賦值,首先添加隱藏標籤到index.cshtml中:
<input type="hidden" id="currentNodeText" /> <input type="hidden" id="currentNodeId" /> <input type="hidden" id="currentHref" />
在節點改變事件綁定的方法中賦值:
angular.element("#dicTree").on('nodeSelected', function (event, data) { angular.element("#currentNodeText").val(data.text); angular.element("#currentNodeId").val(data.id); });
存儲當前選擇的節點是爲了在視圖做用域內持久化節點內容。
組件化模塊(angular component)
解耦複雜系統時將多個功能模塊拆分、重組的過程就叫作模塊化,其中有多個屬性、狀態描述其內部特性。
組件化與傳統的編寫方式相比較,有什麼優點呢,或者叫解決了什麼問題,根據園內CooMark的總結以下:
- app中的某個部分如何重用(在這裏咱們能夠叫作,視圖內的某個模塊如何重用);
- app中的scope做用域不是隔離的,變量和方法存在污染的可能;
- 解決了傳統模式不能重用的問題;
- 簡化了視圖中的標籤,便於維護;
- 組件間是隔離的,互不影響;
- 能夠獨立測試組件;
使用component:
- 文件名建議包含.component.js
- component命名採用駝峯式命名法,在視圖中使用時採用「-」進行分割;
- template使用controller的實例$ctrl替代scope訪問數據,別名可使用controllerAs進行自定義;
- component內的controller能夠經過controller方法進行定義;
- templateUrl定義時須要注意,根目錄爲當前視圖目錄(若是是mvc項目,那麼根目錄就是母版目錄_Layout.cshtml);
定義模塊:
var controllerId = 'app.views.dictionarymanager.index'; var myModule = angular.module("app");
註冊組件到模塊:
- template:元素組件自己;
- templateUrl:經過文件方式定義元素;
- controller:定義組件controller,這樣組件內就能夠經過默認的$ctrl方式調用數據;
- bingdings:綁定數據到元素,其中<爲單向綁定,父做用域的變化影響子做用域;
- scope:組件內單獨的做用域;
- controllerAs:重命名控制器;
- restrict:字符型,E 表示該指令是一個element; A 表示該指令是attribute; C 表示該指令是class; M 表示該指令是注視;
myModule.component('myComp', { //template: '<div>My name is {{$ctrl.text}}</div>', templateUrl:'././App/Main/views/dictionarymanager/dicItem.html', controller: function () { this.name = 'shahar'; }, bindings: { text:'<' }
其中註冊組件能夠經過兩種方式引入模板,第一種經過直接編寫的方式,也就是代碼中template的內容,也能夠經過文件引入的方式,如圖中templateUrl的方式。
視圖中引入組件,視圖中經過-分割駝峯式命名法的組件,並定義綁定的屬性,綁定的屬性能夠經過controller的別名調用父scope內的數據進行綁定:
<my-comp text="vm.dicMainInfo"></my-comp>
父組件向組件傳遞數據:
myModule.controller(controllerId, ['$scope', function ($scope) { this.dicMainInfo = 'hello'; }]);
indes.js代碼以下:
(function () { var controllerId = 'app.views.dictionarymanager.index'; angular.module("app").controller(controllerId, ['$scope', function ($scope) { $scope.AddDictinary = function () { alert("hello"); $scope.btnADCDis = false; }; function initialize() { $scope.srcValue = ""; $scope.btnAddDicCategoryDisabled = true; $scope.btnAddDicDisabled = true; $scope.btnEditDicDisabled = true; $scope.btnDeleteDicDisabled = true; $scope.btnExportDisabled = true; } initialize(); }]); })();
在上面的代碼中實踐了以上介紹的知識點,首先定義controllerId變量,窗體與視圖中ag-controller屬性相同的值,經過module定義模塊,由於在mvc項目中app的div也就是區域已經在模板視圖中定義,因此在定義模塊時統一都是用app名稱進行定義,再經過調用模塊的controller方法建立控制器,控制器中傳遞scope參數,在回調函數中編寫初始化代碼及邏輯代碼,做用域(scopde)中定義的屬性及方法與視圖中的屬性及事件相關聯,這樣即實現了初始化屬性又裝載了事件方法。
錯誤處理
TypeError: $.fn.bootstrapTable is undefined, bootstrap-table-zh-CN.js文件加載錯誤是由於加載順序形成的,加載順序遵循首先加載bootstrap.js文件,而後加載bootstrap-table.js文件,最後加載 bootstrap-table-zh-CN.js文件。